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:
commit
57d31c9777
4 changed files with 87 additions and 3 deletions
|
@ -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
|
||||||
|
|
16
container.go
16
container.go
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue