소스 검색

Merge pull request #13017 from cpuguy83/12859_fix_lxc_wait_exitcodes

Fix LXC stop signals
Alexander Morozov 10 년 전
부모
커밋
71c1a7ea7f
2개의 변경된 파일32개의 추가작업 그리고 11개의 파일을 삭제
  1. 11 4
      daemon/execdriver/lxc/driver.go
  2. 21 7
      integration-cli/docker_cli_wait_test.go

+ 11 - 4
daemon/execdriver/lxc/driver.go

@@ -127,6 +127,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		"lxc-start",
 		"-n", c.ID,
 		"-f", configPath,
+		"-q",
 	}
 
 	// From lxc>=1.1 the default behavior is to daemonize containers after start
@@ -278,19 +279,20 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 	oomKillNotification, err := notifyOnOOM(cgroupPaths)
 
 	<-waitLock
+	exitCode := getExitCode(c)
 
 	if err == nil {
 		_, oomKill = <-oomKillNotification
-		logrus.Debugf("oomKill error %s waitErr %s", oomKill, waitErr)
+		logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr)
 	} else {
 		logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
 	}
 
 	// check oom error
-	exitCode := getExitCode(c)
 	if oomKill {
 		exitCode = 137
 	}
+
 	return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: oomKill}, waitErr
 }
 
@@ -468,7 +470,11 @@ func getExitCode(c *execdriver.Command) int {
 }
 
 func (d *driver) Kill(c *execdriver.Command, sig int) error {
-	return KillLxc(c.ID, sig)
+	if sig == 9 || c.ProcessConfig.Process == nil {
+		return KillLxc(c.ID, sig)
+	}
+
+	return c.ProcessConfig.Process.Signal(syscall.Signal(sig))
 }
 
 func (d *driver) Pause(c *execdriver.Command) error {
@@ -528,7 +534,8 @@ func KillLxc(id string, sig int) error {
 	if err == nil {
 		output, err = exec.Command("lxc-kill", "-n", id, strconv.Itoa(sig)).CombinedOutput()
 	} else {
-		output, err = exec.Command("lxc-stop", "-k", "-n", id, strconv.Itoa(sig)).CombinedOutput()
+		// lxc-stop does not take arbitrary signals like lxc-kill does
+		output, err = exec.Command("lxc-stop", "-k", "-n", id).CombinedOutput()
 	}
 	if err != nil {
 		return fmt.Errorf("Err: %s Output: %s", err, output)

+ 21 - 7
integration-cli/docker_cli_wait_test.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"bytes"
 	"os/exec"
 	"strings"
 	"time"
@@ -44,7 +45,7 @@ func (s *DockerSuite) TestWaitNonBlockedExitZero(c *check.C) {
 
 // blocking wait with 0 exit code
 func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) {
-	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' SIGTERM; while true; do sleep 0.01; done")
+	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' TERM; while true; do sleep 0.01; done")
 	containerID := strings.TrimSpace(out)
 
 	if err := waitRun(containerID); err != nil {
@@ -107,7 +108,7 @@ func (s *DockerSuite) TestWaitNonBlockedExitRandom(c *check.C) {
 
 // blocking wait with random exit code
 func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
-	out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "trap 'exit 99' SIGTERM; while true; do sleep 0.01; done")
+	out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 99' TERM; while true; do sleep 0.01; done")
 	containerID := strings.TrimSpace(out)
 	if err := waitRun(containerID); err != nil {
 		c.Fatal(err)
@@ -116,21 +117,34 @@ func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
 		c.Fatal(err)
 	}
 
-	chWait := make(chan string)
+	chWait := make(chan error)
+	waitCmd := exec.Command(dockerBinary, "wait", containerID)
+	waitCmdOut := bytes.NewBuffer(nil)
+	waitCmd.Stdout = waitCmdOut
+	if err := waitCmd.Start(); err != nil {
+		c.Fatal(err)
+	}
+
 	go func() {
-		out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID))
-		chWait <- out
+		chWait <- waitCmd.Wait()
 	}()
 
-	time.Sleep(100 * time.Millisecond)
 	dockerCmd(c, "stop", containerID)
 
 	select {
-	case status := <-chWait:
+	case err := <-chWait:
+		if err != nil {
+			c.Fatal(err)
+		}
+		status, err := waitCmdOut.ReadString('\n')
+		if err != nil {
+			c.Fatal(err)
+		}
 		if strings.TrimSpace(status) != "99" {
 			c.Fatalf("expected exit 99, got %s", status)
 		}
 	case <-time.After(2 * time.Second):
+		waitCmd.Process.Kill()
 		c.Fatal("timeout waiting for `docker wait` to exit")
 	}
 }