summaryrefslogtreecommitdiff
path: root/libpod/container.go
diff options
context:
space:
mode:
authorMatthew Heon <matthew.heon@gmail.com>2017-11-23 14:06:43 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2017-11-29 12:15:15 +0000
commit831e2c30d479a92c203d2caf82106cb85a6cdfc8 (patch)
tree9c3970ed34441fee8990265685fbdf7654c1af51 /libpod/container.go
parenta1d0d9f5d1d72f3ca0d1d2af36f9542f6f21ff91 (diff)
downloadpodman-831e2c30d479a92c203d2caf82106cb85a6cdfc8.tar.gz
podman-831e2c30d479a92c203d2caf82106cb85a6cdfc8.tar.bz2
podman-831e2c30d479a92c203d2caf82106cb85a6cdfc8.zip
Add ability to kill and stop containers
Also migrates kpod kill and kpod stop to libpod to use the new code Fixes force removing containers, and actually deletes containers in runc when removing them Start is now capable of starting even when the container is unmounted Signed-off-by: Matthew Heon <matthew.heon@gmail.com> Closes: #68 Approved by: rhatdan
Diffstat (limited to 'libpod/container.go')
-rw-r--r--libpod/container.go87
1 files changed, 78 insertions, 9 deletions
diff --git a/libpod/container.go b/libpod/container.go
index b58c156a0..3de0ed02e 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -106,7 +106,7 @@ type ContainerConfig struct {
// reboot
StaticDir string `json:"staticDir"`
// Whether to keep container STDIN open
- Stdin bool
+ Stdin bool `json:"stdin,omitempty"`
// Pod the container belongs to
Pod string `json:"pod,omitempty"`
// Labels is a set of key-value pairs providing additional information
@@ -381,6 +381,7 @@ func (c *Container) teardownStorage() error {
}
c.state.Mounted = false
+ c.state.Mountpoint = ""
}
if err := c.runtime.storageService.DeleteContainer(c.ID()); err != nil {
@@ -474,6 +475,29 @@ func (c *Container) Start() error {
return errors.Wrapf(ErrCtrStateInvalid, "container %s must be in Created or Stopped state to be started", c.ID())
}
+ // If the container isn't mounted, mount it
+ if !c.state.Mounted {
+ mountPoint, err := c.runtime.storageService.StartContainer(c.ID())
+ if err != nil {
+ return errors.Wrapf(err, "error mounting storage for container %s", c.ID())
+ }
+ c.state.Mounted = true
+ c.state.Mountpoint = mountPoint
+
+ logrus.Debugf("Created root filesystem for container %s at %s", c.ID(), c.state.Mountpoint)
+
+ defer func() {
+ if err != nil {
+ if err2 := c.runtime.storageService.StopContainer(c.ID()); err2 != nil {
+ logrus.Errorf("Error unmounting storage for container %s: %v", c.ID(), err2)
+ }
+
+ c.state.Mounted = false
+ c.state.Mountpoint = ""
+ }
+ }()
+ }
+
if err := c.runtime.ociRuntime.startContainer(c); err != nil {
return err
}
@@ -492,14 +516,63 @@ func (c *Container) Start() error {
return nil
}
-// Stop stops a container
-func (c *Container) Stop() error {
- return ErrNotImplemented
+// Stop uses the container's requested stop signal (or SIGTERM if no signal was
+// specified) to stop the container, and if it has not stopped after the given
+// timeout (in seconds), uses SIGKILL to attempt to forcibly stop the container
+// If timeout is 0, SIGKILL will be used immediately
+func (c *Container) Stop(timeout int64) error {
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
+
+ if c.state.State == ContainerStateConfigured ||
+ c.state.State == ContainerStateUnknown ||
+ c.state.State == ContainerStatePaused {
+ return errors.Wrapf(ErrCtrStateInvalid, "can only stop created, running, or stopped containers")
+ }
+
+ if err := c.runtime.ociRuntime.stopContainer(c, timeout); err != nil {
+ return err
+ }
+
+ // Sync the container's state to pick up return code
+ if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil {
+ return err
+ }
+
+ // Also unmount storage
+ if err := c.runtime.storageService.StopContainer(c.ID()); err != nil {
+ return errors.Wrapf(err, "error unmounting container %s root filesystem", c.ID())
+ }
+ c.state.Mountpoint = ""
+ c.state.Mounted = false
+
+ if err := c.runtime.state.SaveContainer(c); err != nil {
+ return errors.Wrapf(err, "error saving container %s state", c.ID())
+ }
+
+ return nil
}
// Kill sends a signal to a container
func (c *Container) Kill(signal uint) error {
- return ErrNotImplemented
+ c.lock.Lock()
+ defer c.lock.Unlock()
+
+ if err := c.syncContainer(); err != nil {
+ return err
+ }
+
+ if c.state.State == ContainerStateUnknown ||
+ c.state.State == ContainerStateConfigured ||
+ c.state.State == ContainerStatePaused {
+ return errors.Wrapf(ErrCtrStateInvalid, "can only kill created, running, or stopped containers")
+ }
+
+ return c.runtime.ociRuntime.killContainer(c, signal)
}
// Exec starts a new process inside the container
@@ -515,10 +588,6 @@ func (c *Container) Attach(noStdin bool, keys string, attached chan<- bool) erro
return err
}
- if c.state.State == ContainerStateRunning || c.state.State == ContainerStatePaused {
- return errors.Wrapf(ErrCtrStateInvalid, "cannot remove storage for container %s as it is running or paused", c.ID())
- }
-
// TODO is it valid to attach to a frozen container?
if c.state.State == ContainerStateUnknown ||
c.state.State == ContainerStateConfigured ||