| ... | ... |
@@ -59,6 +59,20 @@ func assertPipe(input, output string, r io.Reader, w io.Writer, count int) error |
| 59 | 59 |
return nil |
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 |
+func cmdWait(srv *Server, container *Container) error {
|
|
| 63 |
+ stdout, stdoutPipe := io.Pipe() |
|
| 64 |
+ |
|
| 65 |
+ go func() {
|
|
| 66 |
+ srv.CmdWait(nil, stdoutPipe, container.Id) |
|
| 67 |
+ }() |
|
| 68 |
+ |
|
| 69 |
+ if _, err := bufio.NewReader(stdout).ReadString('\n'); err != nil {
|
|
| 70 |
+ return err |
|
| 71 |
+ } |
|
| 72 |
+ // Cleanup pipes |
|
| 73 |
+ return closeWrap(stdout, stdoutPipe) |
|
| 74 |
+} |
|
| 75 |
+ |
|
| 62 | 76 |
// TestRunHostname checks that 'docker run -h' correctly sets a custom hostname |
| 63 | 77 |
func TestRunHostname(t *testing.T) {
|
| 64 | 78 |
runtime, err := newTestRuntime() |
| ... | ... |
@@ -89,7 +103,9 @@ func TestRunHostname(t *testing.T) {
|
| 89 | 89 |
|
| 90 | 90 |
setTimeout(t, "CmdRun timed out", 2*time.Second, func() {
|
| 91 | 91 |
<-c |
| 92 |
+ cmdWait(srv, srv.runtime.List()[0]) |
|
| 92 | 93 |
}) |
| 94 |
+ |
|
| 93 | 95 |
} |
| 94 | 96 |
|
| 95 | 97 |
func TestRunExit(t *testing.T) {
|
| ... | ... |
@@ -129,6 +145,7 @@ func TestRunExit(t *testing.T) {
|
| 129 | 129 |
// as the process exited, CmdRun must finish and unblock. Wait for it |
| 130 | 130 |
setTimeout(t, "Waiting for CmdRun timed out", 2*time.Second, func() {
|
| 131 | 131 |
<-c1 |
| 132 |
+ cmdWait(srv, container) |
|
| 132 | 133 |
}) |
| 133 | 134 |
|
| 134 | 135 |
// Make sure that the client has been disconnected |
| ... | ... |
@@ -551,15 +551,15 @@ func (container *Container) kill() error {
|
| 551 | 551 |
return nil |
| 552 | 552 |
} |
| 553 | 553 |
|
| 554 |
- // Sending SIGINT to the process via lxc |
|
| 554 |
+ // Sending SIGKILL to the process via lxc |
|
| 555 | 555 |
output, err := exec.Command("lxc-kill", "-n", container.Id, "9").CombinedOutput()
|
| 556 | 556 |
if err != nil {
|
| 557 |
- Debugf("error killing container %s (%s, %s)", container.Id, output, err)
|
|
| 557 |
+ log.Printf("error killing container %s (%s, %s)", container.Id, output, err)
|
|
| 558 | 558 |
} |
| 559 | 559 |
|
| 560 | 560 |
// 2. Wait for the process to die, in last resort, try to kill the process directly |
| 561 | 561 |
if err := container.WaitTimeout(10 * time.Second); err != nil {
|
| 562 |
- log.Printf("Container %s failed to exit within 10 seconds of SIGINT - trying direct SIGKILL", container.Id)
|
|
| 562 |
+ log.Printf("Container %s failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL", container.Id)
|
|
| 563 | 563 |
if err := container.cmd.Process.Kill(); err != nil {
|
| 564 | 564 |
return err |
| 565 | 565 |
} |
| ... | ... |
@@ -324,6 +324,54 @@ func TestOutput(t *testing.T) {
|
| 324 | 324 |
} |
| 325 | 325 |
} |
| 326 | 326 |
|
| 327 |
+func TestKillDifferentUser(t *testing.T) {
|
|
| 328 |
+ runtime, err := newTestRuntime() |
|
| 329 |
+ if err != nil {
|
|
| 330 |
+ t.Fatal(err) |
|
| 331 |
+ } |
|
| 332 |
+ defer nuke(runtime) |
|
| 333 |
+ container, err := runtime.Create(&Config{
|
|
| 334 |
+ Image: GetTestImage(runtime).Id, |
|
| 335 |
+ Cmd: []string{"tail", "-f", "/etc/resolv.conf"},
|
|
| 336 |
+ User: "daemon", |
|
| 337 |
+ }, |
|
| 338 |
+ ) |
|
| 339 |
+ if err != nil {
|
|
| 340 |
+ t.Fatal(err) |
|
| 341 |
+ } |
|
| 342 |
+ defer runtime.Destroy(container) |
|
| 343 |
+ |
|
| 344 |
+ if container.State.Running {
|
|
| 345 |
+ t.Errorf("Container shouldn't be running")
|
|
| 346 |
+ } |
|
| 347 |
+ if err := container.Start(); err != nil {
|
|
| 348 |
+ t.Fatal(err) |
|
| 349 |
+ } |
|
| 350 |
+ |
|
| 351 |
+ // Give some time to lxc to spawn the process (setuid might take some time) |
|
| 352 |
+ container.WaitTimeout(500 * time.Millisecond) |
|
| 353 |
+ |
|
| 354 |
+ if !container.State.Running {
|
|
| 355 |
+ t.Errorf("Container should be running")
|
|
| 356 |
+ } |
|
| 357 |
+ |
|
| 358 |
+ if err := container.Kill(); err != nil {
|
|
| 359 |
+ t.Fatal(err) |
|
| 360 |
+ } |
|
| 361 |
+ |
|
| 362 |
+ if container.State.Running {
|
|
| 363 |
+ t.Errorf("Container shouldn't be running")
|
|
| 364 |
+ } |
|
| 365 |
+ container.Wait() |
|
| 366 |
+ if container.State.Running {
|
|
| 367 |
+ t.Errorf("Container shouldn't be running")
|
|
| 368 |
+ } |
|
| 369 |
+ // Try stopping twice |
|
| 370 |
+ if err := container.Kill(); err != nil {
|
|
| 371 |
+ t.Fatal(err) |
|
| 372 |
+ } |
|
| 373 |
+} |
|
| 374 |
+ |
|
| 327 | 375 |
func TestKill(t *testing.T) {
|
| 328 | 376 |
runtime, err := newTestRuntime() |
| 329 | 377 |
if err != nil {
|
| ... | ... |
@@ -346,6 +394,10 @@ func TestKill(t *testing.T) {
|
| 346 | 346 |
if err := container.Start(); err != nil {
|
| 347 | 347 |
t.Fatal(err) |
| 348 | 348 |
} |
| 349 |
+ |
|
| 350 |
+ // Give some time to lxc to spawn the process |
|
| 351 |
+ container.WaitTimeout(500 * time.Millisecond) |
|
| 352 |
+ |
|
| 349 | 353 |
if !container.State.Running {
|
| 350 | 354 |
t.Errorf("Container should be running")
|
| 351 | 355 |
} |
| ... | ... |
@@ -657,6 +709,10 @@ func TestMultipleContainers(t *testing.T) {
|
| 657 | 657 |
t.Fatal(err) |
| 658 | 658 |
} |
| 659 | 659 |
|
| 660 |
+ // Make sure they are running before trying to kill them |
|
| 661 |
+ container1.WaitTimeout(250 * time.Millisecond) |
|
| 662 |
+ container2.WaitTimeout(250 * time.Millisecond) |
|
| 663 |
+ |
|
| 660 | 664 |
// If we are here, both containers should be running |
| 661 | 665 |
if !container1.State.Running {
|
| 662 | 666 |
t.Fatal("Container not running")
|