Skip to content

Commit 4d8e457

Browse files
committed
builder: fallback to legacy
Signed-off-by: CrazyMax <[email protected]>
1 parent 6fef143 commit 4d8e457

4 files changed

Lines changed: 67 additions & 41 deletions

File tree

cli/command/image/build.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
184184
remote string
185185
)
186186

187-
if !options.quiet {
188-
_, _ = fmt.Fprint(dockerCli.Err(), `WARNING: The legacy builder is in use and will build your image in an inefficient way.
187+
if !options.quiet && dockerCli.ServerInfo().OSType != "windows" {
188+
_, _ = fmt.Fprint(dockerCli.Err(), `DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
189189
190190
`)
191191
}

cmd/docker/builder.go

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,31 @@ import (
1414

1515
const (
1616
builderDefaultPlugin = "buildx"
17-
builderDefaultInstallMsg = `To install buildx, see
18-
https://docs.docker.com/go/buildx. You can also fallback to the
19-
legacy builder by setting DOCKER_BUILDKIT=0`
20-
21-
builderErrorMsg = "ERROR: Missing builder component %s."
17+
builderDefaultInstallMsg = `To install buildx, see https://docs.docker.com/go/buildx/`
18+
builderErrorMsg = `%s: Required builder component %s is missing or broken.`
2219
)
2320

2421
type builderError struct {
22+
warn bool
2523
builder string
2624
err error
2725
}
2826

29-
func newBuilderError(builder string, err error) error {
27+
func newBuilderError(warn bool, builder string, err error) error {
3028
return &builderError{
29+
warn: warn,
3130
builder: builder,
3231
err: err,
3332
}
3433
}
3534

3635
func (e *builderError) Error() string {
3736
var errorMsg bytes.Buffer
38-
errorMsg.WriteString(fmt.Sprintf(builderErrorMsg, e.builder))
37+
if e.warn {
38+
errorMsg.WriteString(fmt.Sprintf(builderErrorMsg, "WARNING", e.builder))
39+
} else {
40+
errorMsg.WriteString(fmt.Sprintf(builderErrorMsg, "ERROR", e.builder))
41+
}
3942
if e.builder == builderDefaultPlugin {
4043
errorMsg.WriteString(" ")
4144
errorMsg.WriteString(builderDefaultInstallMsg)
@@ -50,17 +53,19 @@ func (e *builderError) Unwrap() error {
5053
return e.err
5154
}
5255

53-
func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osArgs []string) ([]string, []string, error) {
56+
func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osargs []string) ([]string, []string, error) {
5457
// check DOCKER_BUILDKIT env var is present and
5558
// if not assume we want to use a builder
59+
var enforcedBuilder bool
5660
if v, ok := os.LookupEnv("DOCKER_BUILDKIT"); ok {
5761
enabled, err := strconv.ParseBool(v)
5862
if err != nil {
59-
return args, osArgs, errors.Wrap(err, "DOCKER_BUILDKIT environment variable expects boolean value")
63+
return args, osargs, errors.Wrap(err, "DOCKER_BUILDKIT environment variable expects boolean value")
6064
}
6165
if !enabled {
62-
return args, osArgs, nil
66+
return args, osargs, nil
6367
}
68+
enforcedBuilder = true
6469
}
6570

6671
// if a builder alias is defined, use it instead
@@ -76,48 +81,53 @@ func processBuilder(dockerCli command.Cli, cmd *cobra.Command, args, osArgs []st
7681
// wcow build command must use the legacy builder for buildx
7782
// if not opt-in through a builder alias
7883
if !isAlias && dockerCli.ServerInfo().OSType == "windows" {
79-
return args, osArgs, nil
84+
return args, osargs, nil
85+
}
86+
87+
// are we using a cmd that should be forwarded to the builder?
88+
fwargs, fwosargs, forwarded := forwardBuilder(builderAlias, args, osargs)
89+
if !forwarded {
90+
return args, osargs, nil
91+
}
92+
93+
// check plugin is available if cmd forwarded
94+
plugin, perr := pluginmanager.GetPlugin(builderAlias, dockerCli, cmd.Root())
95+
if perr == nil && plugin != nil {
96+
perr = plugin.Err
97+
}
98+
if perr != nil {
99+
// if builder enforced with DOCKER_BUILDKIT=1, cmd fails if plugin missing or broken
100+
if enforcedBuilder {
101+
return fwargs, fwosargs, newBuilderError(false, builderAlias, perr)
102+
}
103+
// otherwise, display warning and continue
104+
_, _ = fmt.Fprintln(dockerCli.Err(), newBuilderError(true, builderAlias, perr).Error())
105+
return args, osargs, nil
80106
}
81107

82-
// builder aliases
108+
return fwargs, fwosargs, nil
109+
}
110+
111+
func forwardBuilder(alias string, args, osargs []string) ([]string, []string, bool) {
83112
aliases := [][2][]string{
84113
{
85114
{"builder"},
86-
{builderAlias},
115+
{alias},
87116
},
88117
{
89118
{"build"},
90-
{builderAlias, "build"},
119+
{alias, "build"},
91120
},
92121
{
93122
{"image", "build"},
94-
{builderAlias, "build"},
123+
{alias, "build"},
95124
},
96125
}
97-
98-
// are we using a cmd that should be forwarded to the builder?
99-
var forwarded bool
100126
for _, al := range aliases {
101-
var didChange bool
102-
args, didChange = command.StringSliceReplaceAt(args, al[0], al[1], 0)
103-
if didChange {
104-
forwarded = true
105-
osArgs, _ = command.StringSliceReplaceAt(osArgs, al[0], al[1], -1)
106-
break
127+
if fwargs, changed := command.StringSliceReplaceAt(args, al[0], al[1], 0); changed {
128+
fwosargs, _ := command.StringSliceReplaceAt(osargs, al[0], al[1], -1)
129+
return fwargs, fwosargs, true
107130
}
108131
}
109-
if !forwarded {
110-
return args, osArgs, nil
111-
}
112-
113-
// check plugin is available if cmd forwarded
114-
plugin, perr := pluginmanager.GetPlugin(builderAlias, dockerCli, cmd.Root())
115-
if perr == nil && plugin != nil {
116-
perr = plugin.Err
117-
}
118-
if perr != nil {
119-
return args, osArgs, newBuilderError(builderAlias, perr)
120-
}
121-
122-
return args, osArgs, nil
132+
return args, osargs, false
123133
}

docs/deprecated.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ The table below provides an overview of the current status of deprecated feature
5050

5151
Status | Feature | Deprecated | Remove
5252
-----------|------------------------------------------------------------------------------------------------------------------------------------|------------|------------
53+
Deprecated | [Legacy builder fallback](#legacy-builder-fallback) | v21.xx | -
5354
Removed | [Support for encrypted TLS private keys](#support-for-encrypted-tls-private-keys) | v20.10 | v21.xx
5455
Deprecated | [Kubernetes stack and context support](#kubernetes-stack-and-context-support) | v20.10 | -
5556
Deprecated | [Pulling images from non-compliant image registries](#pulling-images-from-non-compliant-image-registries) | v20.10 | -
@@ -99,6 +100,21 @@ Removed | [`--api-enable-cors` flag on `dockerd`](#--api-enable-cors-flag-on-
99100
Removed | [`--run` flag on `docker commit`](#--run-flag-on-docker-commit) | v0.10 | v1.13
100101
Removed | [Three arguments form in `docker import`](#three-arguments-form-in-docker-import) | v0.6.7 | v1.12
101102

103+
### Legacy builder fallback
104+
105+
**Deprecated in Release: v21.xx**
106+
107+
BuildKit implementation code and linked build flags have been removed in the CLI
108+
and are now forwarded to [Buildx](https://docs.docker.com/buildx/working-with-buildx/)
109+
builder component.
110+
111+
If Buildx plugin is missing or broken, build command will fall back to the
112+
legacy builder. This fallback mechanism will be removed in a future release and
113+
user prompted to install the Buildx plugin.
114+
115+
User can always fall back to the legacy builder with `DOCKER_BUILDKIT=0` but
116+
`DOCKER_BUILDKIT=1` will always require Buildx.
117+
102118
### Support for encrypted TLS private keys
103119

104120
**Deprecated in Release: v20.10**

e2e/image/build_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestBuildFromContextDirectoryWithTag(t *testing.T) {
3737
withWorkingDir(dir))
3838
defer icmd.RunCommand("docker", "image", "rm", "myimage")
3939

40-
result.Assert(t, icmd.Expected{Err: "WARNING: The legacy builder is in use and will build your image in an inefficient way."})
40+
result.Assert(t, icmd.Expected{Err: "DEPRECATED: The legacy builder is deprecated and will be removed in a future release."})
4141
output.Assert(t, result.Stdout(), map[int]func(string) error{
4242
0: output.Prefix("Sending build context to Docker daemon"),
4343
1: output.Suffix("Step 1/4 : FROM registry:5000/alpine:3.6"),

0 commit comments

Comments
 (0)