Merge branch 'master' of ssh://github.com/dotcloud/docker
This commit is contained in:
commit
72c0a091c0
3 changed files with 67 additions and 14 deletions
71
container.go
71
container.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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.
Loading…
Reference in a new issue