Skip to content

Commit

Permalink
refactor(build): improve err when file specified by -f does not exist
Browse files Browse the repository at this point in the history
When the user specifies a Containerfile or Dockfile with the -f flag in podman build, if the file does not exist, the error should be intuitive to the user.

Fixed: containers#22940

Signed-off-by: Kevin Cui <bh@bugs.cc>
  • Loading branch information
BlackHole1 committed Jun 18, 2024
1 parent afe55cd commit 5897fdb
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
42 changes: 38 additions & 4 deletions cmd/podman/common/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,7 @@ func ParseBuildOpts(cmd *cobra.Command, args []string, buildOpts *BuildFlagsWrap
// No context directory or URL was specified. Try to use the home of
// the first locally-available Containerfile.
for i := range containerFiles {
if strings.HasPrefix(containerFiles[i], "http://") ||
strings.HasPrefix(containerFiles[i], "https://") ||
strings.HasPrefix(containerFiles[i], "git://") ||
strings.HasPrefix(containerFiles[i], "github.com/") {
if isURL(containerFiles[i]) {
continue
}
absFile, err := filepath.Abs(containerFiles[i])
Expand Down Expand Up @@ -239,6 +236,36 @@ func ParseBuildOpts(cmd *cobra.Command, args []string, buildOpts *BuildFlagsWrap
default:
return nil, fmt.Errorf("no Containerfile or Dockerfile specified or found in context directory, %s: %w", contextDir, syscall.ENOENT)
}
} else {
for _, f := range containerFiles {
if isURL(f) || f == "/dev/stdin" {
continue
}

// If it is a directory, skip it and let buildah handle the situation
// Because currently the podman CI runs the test script buildah/test/bud.bats,
// which checks if the error is a certain string. If we handle it here,
// it will cause the buildah tests to never pass (unless we use the same string).
// See: https://github.com/containers/buildah/blob/4c781b59b49d66e07324566555339888113eb7e2/imagebuildah/build.go#L139-L141
// https://github.com/containers/buildah/blob/4c781b59b49d66e07324566555339888113eb7e2/tests/bud.bats#L3474-L3479
// https://api.cirrus-ci.com/v1/artifact/task/4705206577922048/html/bud-remote-fedora-40-root-host-sqlite.log.html
if utils.IsDir(f) {
continue
}

// If the file is not found, try again with context directory prepended (if not prepended yet)
// Ref: https://github.com/containers/buildah/blob/4c781b59b49d66e07324566555339888113eb7e2/imagebuildah/build.go#L125-L135
if utils.FileExists(f) {
continue
}
if !strings.HasPrefix(f, contextDir) {
if utils.FileExists(filepath.Join(contextDir, f)) {
continue
}
}

return nil, fmt.Errorf("the specified Containerfile or Dockerfile does not exist, %s: %w", f, syscall.ENOENT)
}
}

var logFile *os.File
Expand Down Expand Up @@ -628,3 +655,10 @@ func parseDockerignore(ignoreFile string) ([]string, error) {
}
return excludes, nil
}

func isURL(s string) bool {
return strings.HasPrefix(s, "http://") ||
strings.HasPrefix(s, "https://") ||
strings.HasPrefix(s, "git://") ||
strings.HasPrefix(s, "github.com/")
}
22 changes: 22 additions & 0 deletions test/e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,28 @@ var _ = Describe("Podman build", func() {
Expect(session).Should(ExitCleanly())
})

It("podman build with not found Containerfile or Dockerfile", func() {
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())

targetPath := filepath.Join(podmanTest.TempDir, "notfound")
err = os.Mkdir(targetPath, 0755)
Expect(err).ToNot(HaveOccurred())

Expect(os.Chdir(targetPath)).To(Succeed())
defer func() {
Expect(os.Chdir(cwd)).To(Succeed())
}()

session := podmanTest.Podman([]string{"build", "."})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "no Containerfile or Dockerfile specified or found in context director"))

session = podmanTest.Podman([]string{"build", "-f", "foo"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "the specified Containerfile or Dockerfile does not exist"))
})

It("podman build with logfile", func() {
logfile := filepath.Join(podmanTest.TempDir, "logfile")
session := podmanTest.Podman([]string{"build", "--pull=never", "--tag", "test", "--logfile", logfile, "build/basicalpine"})
Expand Down

0 comments on commit 5897fdb

Please sign in to comment.