diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/containers.go | 13 | ||||
-rw-r--r-- | pkg/bindings/test/containers_test.go | 243 | ||||
-rw-r--r-- | pkg/util/utils_supported.go | 4 |
3 files changed, 258 insertions, 2 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 78057e3f9..08e19edb8 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -469,6 +469,10 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID()) } } + if errors.Cause(err) == define.ErrWillDeadlock { + logrus.Debugf("Deadlock error: %v", err) + return define.ExitCode(err), errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) + } return define.ExitCode(err), err } @@ -702,6 +706,11 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP return exitCode, nil } + if errors.Cause(err) == define.ErrWillDeadlock { + logrus.Debugf("Deadlock error: %v", err) + return define.ExitCode(err), errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) + } + if ctrRunning { return 0, err } @@ -735,6 +744,10 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP if lastError != nil { fmt.Fprintln(os.Stderr, lastError) } + if errors.Cause(err) == define.ErrWillDeadlock { + lastError = errors.Wrapf(err, "please run 'podman system renumber' to resolve deadlocks") + continue + } lastError = errors.Wrapf(err, "unable to start container %q", container) continue } diff --git a/pkg/bindings/test/containers_test.go b/pkg/bindings/test/containers_test.go new file mode 100644 index 000000000..f6ef4abec --- /dev/null +++ b/pkg/bindings/test/containers_test.go @@ -0,0 +1,243 @@ +package test_bindings + +import ( + "context" + "net/http" + "time" + + "github.com/containers/libpod/pkg/bindings" + "github.com/containers/libpod/pkg/bindings/containers" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/onsi/gomega/gexec" +) + +var _ = Describe("Podman containers ", func() { + var ( + bt *bindingTest + s *gexec.Session + connText context.Context + err error + falseFlag bool = false + trueFlag bool = true + ) + + BeforeEach(func() { + bt = newBindingTest() + bt.RestoreImagesFromCache() + s = bt.startAPIService() + time.Sleep(1 * time.Second) + connText, err = bindings.NewConnection(context.Background(), bt.sock) + Expect(err).To(BeNil()) + }) + + AfterEach(func() { + s.Kill() + bt.cleanup() + }) + + It("podman pause a bogus container", func() { + // Pausing bogus container should return 404 + err = containers.Pause(connText, "foobar") + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusNotFound)) + }) + + It("podman unpause a bogus container", func() { + // Unpausing bogus container should return 404 + err = containers.Unpause(connText, "foobar") + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusNotFound)) + }) + + It("podman pause a running container by name", func() { + // Pausing by name should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Pause(connText, name) + Expect(err).To(BeNil()) + + // Ensure container is paused + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + Expect(data.State.Status).To(Equal("paused")) + }) + + It("podman pause a running container by id", func() { + // Pausing by id should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).To(BeNil()) + + // Ensure container is paused + data, err = containers.Inspect(connText, data.ID, nil) + Expect(data.State.Status).To(Equal("paused")) + }) + + It("podman unpause a running container by name", func() { + // Unpausing by name should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Pause(connText, name) + Expect(err).To(BeNil()) + err = containers.Unpause(connText, name) + Expect(err).To(BeNil()) + + // Ensure container is unpaused + data, err := containers.Inspect(connText, name, nil) + Expect(data.State.Status).To(Equal("running")) + }) + + It("podman unpause a running container by ID", func() { + // Unpausing by ID should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + // Pause by name + err := containers.Pause(connText, name) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Unpause(connText, data.ID) + Expect(err).To(BeNil()) + + // Ensure container is unpaused + data, err = containers.Inspect(connText, name, nil) + Expect(data.State.Status).To(Equal("running")) + }) + + It("podman pause a paused container by name", func() { + // Pausing a paused container by name should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Pause(connText, name) + Expect(err).To(BeNil()) + err = containers.Pause(connText, name) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman pause a paused container by id", func() { + // Pausing a paused container by id should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman pause a stopped container by name", func() { + // Pausing a stopped container by name should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Stop(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, name) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman pause a stopped container by id", func() { + // Pausing a stopped container by id should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + err = containers.Stop(connText, data.ID, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman remove a paused container by id without force", func() { + // Removing a paused container without force should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).To(BeNil()) + err = containers.Remove(connText, data.ID, &falseFlag, &falseFlag) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman remove a paused container by id with force", func() { + // Removing a paused container with force should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).To(BeNil()) + err = containers.Remove(connText, data.ID, &trueFlag, &falseFlag) + Expect(err).To(BeNil()) + }) + + It("podman stop a paused container by name", func() { + // Stopping a paused container by name should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Pause(connText, name) + Expect(err).To(BeNil()) + err = containers.Stop(connText, name, nil) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman stop a paused container by id", func() { + // Stopping a paused container by id should fail + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Pause(connText, data.ID) + Expect(err).To(BeNil()) + err = containers.Stop(connText, data.ID, nil) + Expect(err).ToNot(BeNil()) + code, _ := bindings.CheckResponseCode(err) + Expect(code).To(BeNumerically("==", http.StatusInternalServerError)) + }) + + It("podman stop a running container by name", func() { + // Stopping a running container by name should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + err := containers.Stop(connText, name, nil) + Expect(err).To(BeNil()) + + // Ensure container is stopped + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + Expect(data.State.Status).To(Equal("exited")) + }) + + It("podman stop a running container by ID)", func() { + // Stopping a running container by ID should work + var name = "top" + bt.RunTopContainer(&name, &falseFlag, nil) + data, err := containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + err = containers.Stop(connText, data.ID, nil) + Expect(err).To(BeNil()) + + // Ensure container is stopped + data, err = containers.Inspect(connText, name, nil) + Expect(err).To(BeNil()) + Expect(data.State.Status).To(Equal("exited")) + }) + +}) diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go index 0b78a8150..c6aed9943 100644 --- a/pkg/util/utils_supported.go +++ b/pkg/util/utils_supported.go @@ -33,7 +33,7 @@ func GetRuntimeDir() (string, error) { logrus.Debugf("unable to make temp dir %s", tmpDir) } st, err := os.Stat(tmpDir) - if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) { runtimeDir = tmpDir } } @@ -43,7 +43,7 @@ func GetRuntimeDir() (string, error) { logrus.Debugf("unable to make temp dir %s", tmpDir) } st, err := os.Stat(tmpDir) - if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { + if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && (st.Mode().Perm()&0700 == 0700) { runtimeDir = tmpDir } } |