diff --git a/core/docker.go b/core/docker.go index b0c8380..7d374ca 100644 --- a/core/docker.go +++ b/core/docker.go @@ -15,6 +15,7 @@ import ( ) const LatestTag = "latest" +const GracefulShutdownTime = 20 type Docker struct { endPoint string @@ -85,11 +86,16 @@ func (d *Docker) cleanContainers(p *Project) error { for _, c := range l { if c.IsRunning() { Debug("Stoping container and image", "project", p, "container", c.GetShortID(), "end-point", d.endPoint) - if err := d.killContainer(c); err != nil { + if err := d.stopContainer(c); err != nil { return err } } + err := d.waitForGracefulShutdown(c) + if err != nil { + Error(err.Error(), "project", p, "container", c.GetShortID()) + } + Debug("Removing container", "project", p, "container", c.GetShortID(), "end-point", d.endPoint) if err := d.removeContainer(c); err != nil { return err @@ -99,9 +105,8 @@ func (d *Docker) cleanContainers(p *Project) error { return nil } -func (d *Docker) killContainer(c *Container) error { - kopts := docker.KillContainerOptions{ID: c.ID} - if err := d.client.KillContainer(kopts); err != nil { +func (d *Docker) stopContainer(c *Container) error { + if err := d.client.StopContainer(c.ID, GracefulShutdownTime); err != nil { return err } @@ -455,15 +460,33 @@ func (d *Docker) restartLinkedContainers(p *Project) error { return nil } +func (d *Docker) waitForGracefulShutdown(c * Container) error { + timedOut := 0 + isStillRunning := false + for isStillRunning = c.IsRunning(); isStillRunning && timedOut >= GracefulShutdownTime; { + <-time.After(time.Second) + timedOut++ + } + if isStillRunning { + return errors.New("Graceful shutdown timed out on container") + } + return nil +} + func (d *Docker) restartContainer(p *Project, c *Container) error { if !c.IsRunning() { return nil } - if err := d.killContainer(c); err != nil { + if err := d.stopContainer(c); err != nil { return err } + err := d.waitForGracefulShutdown(c) + if err != nil { + Error(err.Error(), "project", p, "container", c.GetShortID()) + } + if err := d.startContainer(p, c); err != nil { return err }