diff --git a/cmd/nerdctl/build.go b/cmd/nerdctl/build.go index 2a6575b4bbd..b7514eab5fc 100644 --- a/cmd/nerdctl/build.go +++ b/cmd/nerdctl/build.go @@ -327,7 +327,6 @@ func generateBuildctlArgs(cmd *cobra.Command, buildkitHost string, platform, arg "--progress=" + progressValue, "--frontend=dockerfile.v0", "--local=context=" + buildContext, - "--local=dockerfile=" + buildContext, "--output=" + output, }...) @@ -336,8 +335,8 @@ func generateBuildctlArgs(cmd *cobra.Command, buildkitHost string, platform, arg return "", nil, false, "", nil, nil, err } - var dir, file string - + dir := buildContext + file := buildkitutil.DefaultDockerfileName if filename != "" { if filename == "-" { var err error @@ -345,7 +344,6 @@ func generateBuildctlArgs(cmd *cobra.Command, buildkitHost string, platform, arg if err != nil { return "", nil, false, "", nil, nil, err } - file = buildkitutil.DefaultDockerfileName cleanup = func() { os.RemoveAll(dir) } @@ -353,11 +351,19 @@ func generateBuildctlArgs(cmd *cobra.Command, buildkitHost string, platform, arg dir, file = filepath.Split(filename) } - if dir != "" { - buildctlArgs = append(buildctlArgs, "--local=dockerfile="+dir) + if dir == "" { + dir = "." } - buildctlArgs = append(buildctlArgs, "--opt=filename="+file) } + absDir, err := filepath.Abs(dir) + if err != nil { + return "", nil, false, "", nil, nil, err + } + if _, err := os.Lstat(filepath.Join(absDir, file)); err != nil { + return "", nil, false, "", nil, nil, err + } + buildctlArgs = append(buildctlArgs, "--local=dockerfile="+dir) + buildctlArgs = append(buildctlArgs, "--opt=filename="+file) target, err := cmd.Flags().GetString("target") if err != nil { diff --git a/cmd/nerdctl/build_test.go b/cmd/nerdctl/build_test.go index e0d216887f3..7ee0ab32552 100644 --- a/cmd/nerdctl/build_test.go +++ b/cmd/nerdctl/build_test.go @@ -140,6 +140,38 @@ CMD ["echo", "nerdctl-build-test-stdin"] base.Cmd("build", "-t", imageName, "-f", "-", ".").CmdOption(testutil.WithStdin(strings.NewReader(dockerfile))).AssertCombinedOutContains(imageName) } +func TestBuildWithDockerfile(t *testing.T) { + testutil.RequiresBuild(t) + base := testutil.NewBase(t) + defer base.Cmd("builder", "prune").Run() + imageName := testutil.Identifier(t) + defer base.Cmd("rmi", imageName).Run() + + dockerfile := fmt.Sprintf(`FROM %s +CMD ["echo", "nerdctl-build-test-dockerfile"] + `, testutil.CommonImage) + + buildCtx := filepath.Join(t.TempDir(), "test") + err := os.MkdirAll(buildCtx, 0755) + assert.NilError(t, err) + err = os.WriteFile(filepath.Join(buildCtx, "Dockerfile"), []byte(dockerfile), 0644) + assert.NilError(t, err) + + pwd, err := os.Getwd() + assert.NilError(t, err) + err = os.Chdir(buildCtx) + assert.NilError(t, err) + defer os.Chdir(pwd) + + // hack os.Getwd return "(unreachable)" on rootless + t.Setenv("PWD", buildCtx) + + base.Cmd("build", "-t", imageName, "-f", "Dockerfile", "..").AssertOK() + base.Cmd("build", "-t", imageName, "-f", "Dockerfile", ".").AssertOK() + // fail err: no such file or directory + base.Cmd("build", "-t", imageName, "-f", "../Dockerfile", ".").AssertFail() +} + func TestBuildLocal(t *testing.T) { t.Parallel() testutil.DockerIncompatible(t)