From 5cc83da1c6bbd07a14bbbdcaea3fc6ce39dae407 Mon Sep 17 00:00:00 2001 From: Alberto Faria Date: Sat, 20 Jan 2024 00:08:43 +0000 Subject: [PATCH] Pass the OCI runtime an empty entrypoint when there is no entrypoint Some OCI runtimes (cf. [1]) may tolerate container images that don't specify an entrypoint even if no entrypoint is given on the command line. In those cases, it's annoying for the user to have to pass a "" argument to podman. If no entrypoint is given, make the behavior the same as if an empty "" entrypoint was given. [1] https://github.com/containers/crun-vm Signed-off-by: Alberto Faria --- pkg/specgen/generate/container_create.go | 5 +---- pkg/specgen/generate/oci.go | 9 +++++---- test/e2e/run_entrypoint_test.go | 2 +- test/system/030-run.bats | 16 ++++++++++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 1fbdf7b7d6..6c71263248 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -226,10 +226,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener options = append(options, libpod.WithHostUsers(s.HostUsers)) } - command, err := makeCommand(s, imageData) - if err != nil { - return nil, nil, nil, err - } + command := makeCommand(s, imageData) infraVol := len(compatibleOptions.Mounts) > 0 || len(compatibleOptions.Volumes) > 0 || len(compatibleOptions.ImageVolumes) > 0 || len(compatibleOptions.OverlayVolumes) > 0 opts, err := createContainerOptions(rt, s, pod, finalVolumes, finalOverlays, imageData, command, infraVol, *compatibleOptions) diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go index 59cd99e70a..07fa1a8709 100644 --- a/pkg/specgen/generate/oci.go +++ b/pkg/specgen/generate/oci.go @@ -3,13 +3,13 @@ package generate import ( - "fmt" "strings" "github.com/containers/common/libimage" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/pkg/specgen" "github.com/opencontainers/runtime-tools/generate" + "github.com/sirupsen/logrus" ) func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) { @@ -23,7 +23,7 @@ func addRlimits(s *specgen.SpecGenerator, g *generate.Generator) { } // Produce the final command for the container. -func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]string, error) { +func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData) []string { finalCommand := []string{} entrypoint := s.Entrypoint @@ -46,7 +46,8 @@ func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]str finalCommand = append(finalCommand, command...) if len(finalCommand) == 0 { - return nil, fmt.Errorf("no command or entrypoint provided, and no CMD or ENTRYPOINT from image") + logrus.Debug("no command or entrypoint provided, and no CMD or ENTRYPOINT from image: defaulting to empty string") + finalCommand = []string{""} } if s.Init { @@ -54,5 +55,5 @@ func makeCommand(s *specgen.SpecGenerator, imageData *libimage.ImageData) ([]str finalCommand = append([]string{define.ContainerInitPath, "--"}, finalCommand...) } - return finalCommand, nil + return finalCommand } diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go index 6e11dc4e30..cb6ec278af 100644 --- a/test/e2e/run_entrypoint_test.go +++ b/test/e2e/run_entrypoint_test.go @@ -17,7 +17,7 @@ CMD [] podmanTest.BuildImage(dockerfile, "foobar.com/entrypoint:latest", "false") session := podmanTest.Podman([]string{"run", "foobar.com/entrypoint:latest"}) session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(125)) + Expect(session).Should(Or(Exit(126), Exit(127))) }) It("podman run entrypoint == [\"\"]", func() { diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 0642404501..7b302cb918 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -1415,4 +1415,20 @@ search | $IMAGE | run_podman rmi $(pause_image) } +@test "podman run - no entrypoint" { + run_podman 127 run --rm --rootfs "$PODMAN_TMPDIR" + + # runc and crun emit different diagnostics + runtime=$(podman_runtime) + case "$runtime" in + crun) expect='crun: executable file `` not found in $PATH: No such file or directory: OCI runtime attempted to invoke a command that was not found' ;; + runc) expect='runc: runc create failed: unable to start container process: exec: "": executable file not found in $PATH: OCI runtime attempted to invoke a command that was not found' ;; + *) skip "Unknown runtime '$runtime'" ;; + esac + + # The '.*' in the error below is for dealing with podman-remote, which + # includes "error preparing container for attach" in output. + is "$output" "Error.*: $expect" "podman emits useful diagnostic when no entrypoint is set" +} + # vim: filetype=sh