Merge branch 'master' of ssh://github.com/dotcloud/docker

This commit is contained in:
Solomon Hykes 2013-01-21 18:15:19 -08:00
commit 72c0a091c0
3 changed files with 67 additions and 14 deletions

View file

@ -5,10 +5,12 @@ import (
"errors"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"path"
"syscall"
"time"
)
type Container struct {
@ -176,22 +178,57 @@ func (container *Container) StderrPipe() (io.ReadCloser, error) {
func (container *Container) monitor() {
container.cmd.Wait()
exitCode := container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
// Cleanup container
container.stdout.Close()
container.stderr.Close()
container.State.setStopped(container.cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus())
if err := container.Filesystem.Umount(); err != nil {
log.Printf("%v: Failed to umount filesystem: %v", container.Name, err)
}
// Report status back
container.State.setStopped(exitCode)
}
func (container *Container) kill() error {
// This will cause the main container process to receive a SIGKILL
if err := exec.Command("/usr/bin/lxc-stop", "-n", container.Name).Run(); err != nil {
return err
}
// Wait for the container to be actually stopped
if err := exec.Command("/usr/bin/lxc-wait", "-n", container.Name, "-s", "STOPPED").Run(); err != nil {
return err
}
return nil
}
func (container *Container) Kill() error {
if !container.State.Running {
return nil
}
return container.kill()
}
func (container *Container) Stop() error {
if container.State.Running {
if err := exec.Command("/usr/bin/lxc-stop", "-n", container.Name).Run(); err != nil {
return err
}
//FIXME: We should lxc-wait for the container to stop
if !container.State.Running {
return nil
}
if err := container.Filesystem.Umount(); err != nil {
// FIXME: Do not abort, probably already umounted?
return nil
// 1. Send a SIGTERM
if err := exec.Command("/usr/bin/lxc-kill", "-n", container.Name, "15").Run(); err != nil {
return err
}
// 2. Wait for the process to exit on its own
if err := container.WaitTimeout(10 * time.Second); err != nil {
log.Printf("Container %v failed to exit within 10 seconds of SIGTERM", container.Name)
}
// 3. Force kill
if err := container.kill(); err != nil {
return err
}
return nil
}
@ -201,3 +238,19 @@ func (container *Container) Wait() {
container.State.wait()
}
}
func (container *Container) WaitTimeout(timeout time.Duration) error {
done := make(chan bool)
go func() {
container.Wait()
done <- true
}()
select {
case <-time.After(timeout):
return errors.New("Timed Out")
case <-done:
return nil
}
return nil
}

View file

@ -98,15 +98,15 @@ func TestOutput(t *testing.T) {
}
}
func TestStop(t *testing.T) {
func TestKill(t *testing.T) {
docker, err := newTestDocker()
if err != nil {
t.Fatal(err)
}
container, err := docker.Create(
"stop_test",
"sleep",
[]string{"300"},
"cat",
[]string{"/dev/zero"},
[]string{"/var/lib/docker/images/ubuntu"},
&Config{},
)
@ -124,7 +124,7 @@ func TestStop(t *testing.T) {
if !container.State.Running {
t.Errorf("Container should be running")
}
if err := container.Stop(); err != nil {
if err := container.Kill(); err != nil {
t.Fatal(err)
}
if container.State.Running {
@ -135,7 +135,7 @@ func TestStop(t *testing.T) {
t.Errorf("Container shouldn't be running")
}
// Try stopping twice
if err := container.Stop(); err != nil {
if err := container.Kill(); err != nil {
t.Fatal(err)
}
}

Binary file not shown.