diff options
author | Matthew Heon <matthew.heon@gmail.com> | 2017-11-23 14:06:43 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2017-11-29 12:15:15 +0000 |
commit | 831e2c30d479a92c203d2caf82106cb85a6cdfc8 (patch) | |
tree | 9c3970ed34441fee8990265685fbdf7654c1af51 /libpod/container.go | |
parent | a1d0d9f5d1d72f3ca0d1d2af36f9542f6f21ff91 (diff) | |
download | podman-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.go | 87 |
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 || |