From 4c5e76b26e2a1305f96cf27b0d7fabd6e0315058 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Fri, 27 Apr 2018 18:40:59 +0800 Subject: [PATCH 1/2] Fix the target name issue for multi-stage build This PR is trying to fix issue #36956. The stage name is case-insensitive by design, so we should use `strings.EqualFold()` as the comparison method to eliminate the case sensitive noise. Also we need to return a pre-defined error code order to avoid below message like: "FIXME: Got an API for which error does not match any expected type!!!: failed to reach build target dev in Dockerfile" Signed-off-by: Dennis Chen Upstream-commit: 7c0570473cfa181aeb3278072cc9af4f9298cb98 Component: engine --- components/engine/builder/dockerfile/builder.go | 2 +- components/engine/builder/dockerfile/instructions/commands.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/components/engine/builder/dockerfile/builder.go b/components/engine/builder/dockerfile/builder.go index cdc75c3c32..cd2fa7c56b 100644 --- a/components/engine/builder/dockerfile/builder.go +++ b/components/engine/builder/dockerfile/builder.go @@ -226,7 +226,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil targetIx, found := instructions.HasStage(stages, b.options.Target) if !found { buildsFailed.WithValues(metricsBuildTargetNotReachableError).Inc() - return nil, errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target) + return nil, errdefs.InvalidParameter(errors.Errorf("failed to reach build target %s in Dockerfile", b.options.Target)) } stages = stages[:targetIx+1] } diff --git a/components/engine/builder/dockerfile/instructions/commands.go b/components/engine/builder/dockerfile/instructions/commands.go index a10140cf04..9d864e5325 100644 --- a/components/engine/builder/dockerfile/instructions/commands.go +++ b/components/engine/builder/dockerfile/instructions/commands.go @@ -390,7 +390,8 @@ func CurrentStage(s []Stage) (*Stage, error) { // HasStage looks for the presence of a given stage name func HasStage(s []Stage, name string) (int, bool) { for i, stage := range s { - if stage.Name == name { + // Stage name is case-insensitive by design + if strings.EqualFold(stage.Name, name) { return i, true } } From 0e7b49da2ede169bc4a72c6a5a0289984034f445 Mon Sep 17 00:00:00 2001 From: Dennis Chen Date: Sat, 28 Apr 2018 15:45:23 +0800 Subject: [PATCH 2/2] Add `--target` name case sensitive test code for multi-stage build Add testing code to cover the `--target` name case sensitive issue reported by issue #36956. Signed-off-by: Dennis Chen Upstream-commit: a95fabc70efacc1ff6c0c62c490cf551215bc503 Component: engine --- .../engine/integration-cli/docker_cli_build_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/engine/integration-cli/docker_cli_build_test.go b/components/engine/integration-cli/docker_cli_build_test.go index cd57d591f2..2ed5e44d8f 100644 --- a/components/engine/integration-cli/docker_cli_build_test.go +++ b/components/engine/integration-cli/docker_cli_build_test.go @@ -5965,10 +5965,16 @@ func (s *DockerSuite) TestBuildIntermediateTarget(c *check.C) { cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx), cli.WithFlags("--target", "build-env")) - //res := inspectFieldJSON(c, "build1", "Config.Cmd") res := cli.InspectCmd(c, "build1", cli.Format("json .Config.Cmd")).Combined() c.Assert(strings.TrimSpace(res), checker.Equals, `["/dev"]`) + // Stage name is case-insensitive by design + cli.BuildCmd(c, "build1", build.WithExternalBuildContext(ctx), + cli.WithFlags("--target", "BUIld-EnV")) + + res = cli.InspectCmd(c, "build1", cli.Format("json .Config.Cmd")).Combined() + c.Assert(strings.TrimSpace(res), checker.Equals, `["/dev"]`) + result := cli.Docker(cli.Build("build1"), build.WithExternalBuildContext(ctx), cli.WithFlags("--target", "nosuchtarget")) result.Assert(c, icmd.Expected{