1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge remote-tracking branch 'origin/kill_behaviour_fix'

This commit is contained in:
Solomon Hykes 2013-04-12 10:20:26 -07:00
commit 57d31c9777
4 changed files with 87 additions and 3 deletions

View file

@ -59,6 +59,20 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error
return nil return nil
} }
func cmdWait(srv *Server, container *Container) error {
stdout, stdoutPipe := io.Pipe()
go func() {
srv.CmdWait(nil, stdoutPipe, container.Id)
}()
if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
return err
}
// Cleanup pipes
return closeWrap(stdout, stdoutPipe)
}
// TestRunHostname checks that 'docker run -h' correctly sets a custom hostname // TestRunHostname checks that 'docker run -h' correctly sets a custom hostname
func TestRunHostname(t *testing.T) { func TestRunHostname(t *testing.T) {
runtime, err := newTestRuntime() runtime, err := newTestRuntime()
@ -89,7 +103,9 @@ func TestRunHostname(t *testing.T) {
setTimeout(t, "CmdRun timed out", 2*time.Second, func() { setTimeout(t, "CmdRun timed out", 2*time.Second, func() {
<-c <-c
cmdWait(srv, srv.runtime.List()[0])
}) })
} }
func TestRunExit(t *testing.T) { func TestRunExit(t *testing.T) {
@ -129,6 +145,7 @@ func TestRunExit(t *testing.T) {
// as the process exited, CmdRun must finish and unblock. Wait for it // as the process exited, CmdRun must finish and unblock. Wait for it
setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() { setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() {
<-c1 <-c1
cmdWait(srv, container)
}) })
// Make sure that the client has been disconnected // Make sure that the client has been disconnected

View file

@ -550,9 +550,21 @@ func (container *Container) kill() error {
if !container.State.Running || container.cmd == nil { if !container.State.Running || container.cmd == nil {
return nil return nil
} }
if err := container.cmd.Process.Kill(); err != nil {
return err // Sending SIGKILL to the process via lxc
output, err := exec.Command("lxc-kill", "-n", container.Id, "9").CombinedOutput()
if err != nil {
log.Printf("error killing container %s (%s, %s)", container.Id, output, err)
} }
// 2. Wait for the process to die, in last resort, try to kill the process directly
if err := container.WaitTimeout(10 * time.Second); err != nil {
log.Printf("Container %s failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL", container.Id)
if err := container.cmd.Process.Kill(); err != nil {
return err
}
}
// Wait for the container to be actually stopped // Wait for the container to be actually stopped
container.Wait() container.Wait()
return nil return nil

View file

@ -324,6 +324,54 @@ func TestOutput(t *testing.T) {
} }
} }
func TestKillDifferentUser(t *testing.T) {
runtime, err := newTestRuntime()
if err != nil {
t.Fatal(err)
}
defer nuke(runtime)
container, err := runtime.Create(&Config{
Image: GetTestImage(runtime).Id,
Cmd: []string{"tail", "-f", "/etc/resolv.conf"},
User: "daemon",
},
)
if err != nil {
t.Fatal(err)
}
defer runtime.Destroy(container)
if container.State.Running {
t.Errorf("Container shouldn't be running")
}
if err := container.Start(); err != nil {
t.Fatal(err)
}
// Give some time to lxc to spawn the process (setuid might take some time)
container.WaitTimeout(500 * time.Millisecond)
if !container.State.Running {
t.Errorf("Container should be running")
}
if err := container.Kill(); err != nil {
t.Fatal(err)
}
if container.State.Running {
t.Errorf("Container shouldn't be running")
}
container.Wait()
if container.State.Running {
t.Errorf("Container shouldn't be running")
}
// Try stopping twice
if err := container.Kill(); err != nil {
t.Fatal(err)
}
}
func TestKill(t *testing.T) { func TestKill(t *testing.T) {
runtime, err := newTestRuntime() runtime, err := newTestRuntime()
if err != nil { if err != nil {
@ -346,6 +394,10 @@ func TestKill(t *testing.T) {
if err := container.Start(); err != nil { if err := container.Start(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Give some time to lxc to spawn the process
container.WaitTimeout(500 * time.Millisecond)
if !container.State.Running { if !container.State.Running {
t.Errorf("Container should be running") t.Errorf("Container should be running")
} }
@ -657,6 +709,10 @@ func TestMultipleContainers(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// Make sure they are running before trying to kill them
container1.WaitTimeout(250 * time.Millisecond)
container2.WaitTimeout(250 * time.Millisecond)
// If we are here, both containers should be running // If we are here, both containers should be running
if !container1.State.Running { if !container1.State.Running {
t.Fatal("Container not running") t.Fatal("Container not running")

View file

@ -17,7 +17,6 @@ const testLayerPath string = "/var/lib/docker/docker-ut.tar"
const unitTestImageName string = "docker-ut" const unitTestImageName string = "docker-ut"
var unitTestStoreBase string var unitTestStoreBase string
var srv *Server
func nuke(runtime *Runtime) error { func nuke(runtime *Runtime) error {
var wg sync.WaitGroup var wg sync.WaitGroup