mirror of
https://github.com/containers/podman.git
synced 2025-06-29 15:08:09 +08:00
Add StopWithTimeout API function for containers
Normal Stop should not need a timeout, and should use the default Add a function that does accept a timeout aside it Signed-off-by: Matthew Heon <mheon@redhat.com> Closes: #272 Approved by: rhatdan
This commit is contained in:
@ -101,7 +101,7 @@ func stopCmd(c *cli.Context) error {
|
|||||||
} else {
|
} else {
|
||||||
stopTimeout = ctr.StopTimeout()
|
stopTimeout = ctr.StopTimeout()
|
||||||
}
|
}
|
||||||
if err := ctr.Stop(stopTimeout); err != nil {
|
if err := ctr.StopWithTimeout(stopTimeout); err != nil {
|
||||||
if lastError != nil {
|
if lastError != nil {
|
||||||
fmt.Fprintln(os.Stderr, lastError)
|
fmt.Fprintln(os.Stderr, lastError)
|
||||||
}
|
}
|
||||||
|
@ -326,10 +326,11 @@ func (c *Container) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop uses the container's stop signal (or SIGTERM if no signal was specified)
|
// Stop uses the container's stop signal (or SIGTERM if no signal was specified)
|
||||||
// to stop the container, and if it has not stopped after the given timeout (in
|
// to stop the container, and if it has not stopped after container's stop
|
||||||
// seconds), uses SIGKILL to attempt to forcibly stop the container.
|
// timeout, SIGKILL is used to attempt to forcibly stop the container
|
||||||
// If timeout is 0, SIGKILL will be used immediately
|
// Default stop timeout is 10 seconds, but can be overridden when the container
|
||||||
func (c *Container) Stop(timeout uint) error {
|
// is created
|
||||||
|
func (c *Container) Stop() error {
|
||||||
if !c.locked {
|
if !c.locked {
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
@ -339,24 +340,23 @@ func (c *Container) Stop(timeout uint) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
|
return c.stop(c.config.StopTimeout)
|
||||||
|
}
|
||||||
|
|
||||||
if c.state.State == ContainerStateConfigured ||
|
// StopWithTimeout is a version of Stop that allows a timeout to be specified
|
||||||
c.state.State == ContainerStateUnknown ||
|
// manually. If timeout is 0, SIGKILL will be used immediately to kill the
|
||||||
c.state.State == ContainerStatePaused {
|
// container.
|
||||||
return errors.Wrapf(ErrCtrStateInvalid, "can only stop created, running, or stopped containers")
|
func (c *Container) StopWithTimeout(timeout uint) error {
|
||||||
|
if !c.locked {
|
||||||
|
c.lock.Lock()
|
||||||
|
defer c.lock.Unlock()
|
||||||
|
|
||||||
|
if err := c.syncContainer(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.runtime.ociRuntime.stopContainer(c, timeout); err != nil {
|
return c.stop(timeout)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sync the container's state to pick up return code
|
|
||||||
if err := c.runtime.ociRuntime.updateContainerStatus(c); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.cleanupStorage()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill sends a signal to a container
|
// Kill sends a signal to a container
|
||||||
|
@ -302,6 +302,28 @@ func (c *Container) save() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal, non-locking function to stop container
|
||||||
|
func (c *Container) stop(timeout uint) error {
|
||||||
|
logrus.Debugf("Stopping ctr %s with timeout %d", c.ID(), timeout)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.cleanupStorage()
|
||||||
|
}
|
||||||
|
|
||||||
// mountStorage sets up the container's root filesystem
|
// mountStorage sets up the container's root filesystem
|
||||||
// It mounts the image and any other requested mounts
|
// It mounts the image and any other requested mounts
|
||||||
// TODO: Add ability to override mount label so we can use this for Mount() too
|
// TODO: Add ability to override mount label so we can use this for Mount() too
|
||||||
|
@ -299,7 +299,7 @@ func (r *Runtime) Shutdown(force bool) error {
|
|||||||
logrus.Errorf("Error retrieving containers from database: %v", err)
|
logrus.Errorf("Error retrieving containers from database: %v", err)
|
||||||
} else {
|
} else {
|
||||||
for _, ctr := range ctrs {
|
for _, ctr := range ctrs {
|
||||||
if err := ctr.Stop(CtrRemoveTimeout); err != nil {
|
if err := ctr.StopWithTimeout(CtrRemoveTimeout); err != nil {
|
||||||
logrus.Errorf("Error stopping container %s: %v", ctr.ID(), err)
|
logrus.Errorf("Error stopping container %s: %v", ctr.ID(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user