Merge pull request #11513 from Luap99/unshare

podman unshare keep exit code
This commit is contained in:
OpenShift Merge Robot
2021-09-11 17:26:35 -04:00
committed by GitHub
3 changed files with 82 additions and 3 deletions

View File

@ -2,6 +2,7 @@ package system
import (
"os"
"os/exec"
"github.com/containers/common/pkg/completion"
"github.com/containers/podman/v3/cmd/podman/registry"
@ -50,5 +51,23 @@ func unshare(cmd *cobra.Command, args []string) error {
args = []string{shell}
}
return registry.ContainerEngine().Unshare(registry.Context(), args, unshareOptions)
err := registry.ContainerEngine().Unshare(registry.Context(), args, unshareOptions)
if err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
// the user command inside the unshare env has failed
// we set the exit code, do not return the error to the user
// otherwise "exit status X" will be printed
registry.SetExitCode(exitError.ExitCode())
return nil
}
// cmd.Run() can return fs.ErrNotExist, fs.ErrPermission or exec.ErrNotFound
// follow podman run/exec standard with the exit codes
if errors.Is(err, os.ErrNotExist) || errors.Is(err, exec.ErrNotFound) {
registry.SetExitCode(127)
} else if errors.Is(err, os.ErrPermission) {
registry.SetExitCode(126)
}
return err
}
return nil
}

View File

@ -37,6 +37,35 @@ connect to a rootless container via IP address (CNI networking). This is otherwi
not possible from the host network namespace.
_Note: Using this option with more than one unshare session can have unexpected results._
## Exit Codes
The exit code from `podman unshare` gives information about why the container
failed to run or why it exited. When `podman unshare` commands exit with a non-zero code,
the exit codes follow the `chroot` standard, see below:
**125** The error is with podman **_itself_**
$ podman unshare --foo; echo $?
Error: unknown flag: --foo
125
**126** Executing a _contained command_ and the _command_ cannot be invoked
$ podman unshare /etc; echo $?
Error: fork/exec /etc: permission denied
126
**127** Executing a _contained command_ and the _command_ cannot be found
$ podman run busybox foo; echo $?
Error: fork/exec /usr/bin/bogus: no such file or directory
127
**Exit code** _contained command_ exit code
$ podman run busybox /bin/sh -c 'exit 3'; echo $?
3
## EXAMPLE
```

View File

@ -47,8 +47,7 @@ var _ = Describe("Podman unshare", func() {
session := podmanTest.Podman([]string{"unshare", "readlink", "/proc/self/ns/user"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
ok, _ := session.GrepString(userNS)
Expect(ok).To(BeFalse())
Expect(session.OutputToString()).ToNot(ContainSubstring(userNS))
})
It("podman unshare --rootles-cni", func() {
@ -57,4 +56,36 @@ var _ = Describe("Podman unshare", func() {
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring("tap0"))
})
It("podman unshare exit codes", func() {
session := podmanTest.Podman([]string{"unshare", "false"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
Expect(session.OutputToString()).Should(Equal(""))
Expect(session.ErrorToString()).Should(Equal(""))
session = podmanTest.Podman([]string{"unshare", "/usr/bin/bogus"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(127))
Expect(session.OutputToString()).Should(Equal(""))
Expect(session.ErrorToString()).Should(ContainSubstring("no such file or directory"))
session = podmanTest.Podman([]string{"unshare", "bogus"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(127))
Expect(session.OutputToString()).Should(Equal(""))
Expect(session.ErrorToString()).Should(ContainSubstring("executable file not found in $PATH"))
session = podmanTest.Podman([]string{"unshare", "/usr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(126))
Expect(session.OutputToString()).Should(Equal(""))
Expect(session.ErrorToString()).Should(ContainSubstring("permission denied"))
session = podmanTest.Podman([]string{"unshare", "--bogus"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(125))
Expect(session.OutputToString()).Should(Equal(""))
Expect(session.ErrorToString()).Should(ContainSubstring("unknown flag: --bogus"))
})
})