diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2018-04-17 11:07:33 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-04-17 16:00:34 +0000 |
commit | 96d11622c60e80e706c7bc18a096dc0a762f3e9f (patch) | |
tree | cb58eccf57e25234735626c30d50ca3f4cb21ffc | |
parent | 64497042324e9f6ff6663e3dd5c61157f4137531 (diff) | |
download | podman-96d11622c60e80e706c7bc18a096dc0a762f3e9f.tar.gz podman-96d11622c60e80e706c7bc18a096dc0a762f3e9f.tar.bz2 podman-96d11622c60e80e706c7bc18a096dc0a762f3e9f.zip |
Allow podman to exit exit codes of removed containers
We can read the exit file created by conmon to get the exit code
instead of querying libpod.
Also, do not error on cleanup if the container is already gone,
as a completely removed container is definitely cleaned up.
Resolves: #527
Signed-off-by: Matthew Heon <matthew.heon@gmail.com>
Closes: #632
Approved by: rhatdan
-rw-r--r-- | cmd/podman/run.go | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/cmd/podman/run.go b/cmd/podman/run.go index da506c2bd..2bf0668a3 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -3,7 +3,10 @@ package main import ( "encoding/json" "fmt" + "io/ioutil" "os" + "path/filepath" + "strconv" "strings" "github.com/pkg/errors" @@ -189,7 +192,18 @@ func runCmd(c *cli.Context) error { } if ecode, err := ctr.ExitCode(); err != nil { - logrus.Errorf("unable to get exit code of container %s: %q", ctr.ID(), err) + if errors.Cause(err) == libpod.ErrNoSuchCtr { + // The container may have been removed + // Go looking for an exit file + ctrExitCode, err := readExitFile(runtime.GetConfig().TmpDir, ctr.ID()) + if err != nil { + logrus.Errorf("Cannot get exit code: %v", err) + } else { + exitCode = ctrExitCode + } + } else { + logrus.Errorf("Unable to get exit code of container %s: %q", ctr.ID(), err) + } } else { exitCode = int(ecode) } @@ -197,5 +211,40 @@ func runCmd(c *cli.Context) error { if createConfig.Rm { return runtime.RemoveContainer(ctr, true) } - return ctr.Cleanup() + + if err := ctr.Cleanup(); err != nil { + // If the container has been removed already, no need to error on cleanup + if errors.Cause(err) == libpod.ErrNoSuchCtr || errors.Cause(err) == libpod.ErrCtrRemoved { + return nil + } + + return err + } + + return nil +} + +// Read a container's exit file +func readExitFile(runtimeTmp, ctrID string) (int, error) { + exitFile := filepath.Join(runtimeTmp, "exits", ctrID) + + logrus.Debugf("Attempting to read container %s exit code from file %s", ctrID, exitFile) + + // Check if it exists + if _, err := os.Stat(exitFile); err != nil { + return 0, errors.Wrapf(err, "error getting exit file for container %s", ctrID) + } + + // File exists, read it in and convert to int + statusStr, err := ioutil.ReadFile(exitFile) + if err != nil { + return 0, errors.Wrapf(err, "error reading exit file for container %s", ctrID) + } + + exitCode, err := strconv.Atoi(string(statusStr)) + if err != nil { + return 0, errors.Wrapf(err, "error parsing exit code for container %s", ctrID) + } + + return exitCode, nil } |