Use go timers for kill docker by timeout, fixes #12
此提交包含在:
		@@ -14,6 +14,7 @@ import (
 | 
			
		||||
	"os/user"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/jollheef/out-of-tree/config"
 | 
			
		||||
	"github.com/naoina/toml"
 | 
			
		||||
@@ -33,8 +34,7 @@ func matchDebianHeadersPkg(container, mask string, generic bool) (
 | 
			
		||||
	pkgs []string, err error) {
 | 
			
		||||
 | 
			
		||||
	cmd := "apt-cache search linux-headers | cut -d ' ' -f 1"
 | 
			
		||||
	c := dockerCommand(container, "/tmp", "1m", cmd)
 | 
			
		||||
	rawOutput, err := c.CombinedOutput()
 | 
			
		||||
	output, err := dockerRun(time.Minute, container, "/tmp", cmd)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@@ -44,7 +44,7 @@ func matchDebianHeadersPkg(container, mask string, generic bool) (
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kernels := r.FindAll(rawOutput, -1)
 | 
			
		||||
	kernels := r.FindAll([]byte(output), -1)
 | 
			
		||||
 | 
			
		||||
	for _, k := range kernels {
 | 
			
		||||
		pkg := string(k)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.go
									
									
									
									
									
								
							@@ -124,7 +124,7 @@ func main() {
 | 
			
		||||
		"Create directories && download images")
 | 
			
		||||
 | 
			
		||||
	// Check for required commands
 | 
			
		||||
	for _, cmd := range []string{"timeout", "docker", "qemu-system-x86_64"} {
 | 
			
		||||
	for _, cmd := range []string{"docker", "qemu-system-x86_64"} {
 | 
			
		||||
		_, err := exec.Command("which", cmd).CombinedOutput()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalln("Command not found:", cmd)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								pew.go
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								pew.go
									
									
									
									
									
								
							@@ -26,10 +26,24 @@ import (
 | 
			
		||||
 | 
			
		||||
var somethingFailed = false
 | 
			
		||||
 | 
			
		||||
func dockerCommand(container, workdir, timeout, command string) *exec.Cmd {
 | 
			
		||||
	return exec.Command("timeout", "-k", timeout, timeout, "docker", "run",
 | 
			
		||||
		"-v", workdir+":/work", container,
 | 
			
		||||
		"bash", "-c", "cd /work && "+command)
 | 
			
		||||
func dockerRun(timeout time.Duration, container, workdir, command string) (
 | 
			
		||||
	output string, err error) {
 | 
			
		||||
 | 
			
		||||
	cmd := exec.Command("docker", "run", "-v", workdir+":/work",
 | 
			
		||||
		container, "bash", "-c", "cd /work && "+command)
 | 
			
		||||
 | 
			
		||||
	timer := time.AfterFunc(timeout, func() {
 | 
			
		||||
		cmd.Process.Kill()
 | 
			
		||||
	})
 | 
			
		||||
	defer timer.Stop()
 | 
			
		||||
 | 
			
		||||
	raw, err := cmd.CombinedOutput()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	output = string(raw)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func build(tmp string, ka config.Artifact, ki config.KernelInfo,
 | 
			
		||||
@@ -51,11 +65,8 @@ func build(tmp string, ka config.Artifact, ki config.KernelInfo,
 | 
			
		||||
 | 
			
		||||
	kernel := "/lib/modules/" + ki.KernelRelease + "/build"
 | 
			
		||||
 | 
			
		||||
	seconds := fmt.Sprintf("%ds", dockerTimeout/time.Second)
 | 
			
		||||
	cmd := dockerCommand(ki.ContainerName, tmpSourcePath, seconds,
 | 
			
		||||
		"make KERNEL="+kernel+" TARGET="+target)
 | 
			
		||||
	rawOutput, err := cmd.CombinedOutput()
 | 
			
		||||
	output = string(rawOutput)
 | 
			
		||||
	output, err = dockerRun(dockerTimeout, ki.ContainerName,
 | 
			
		||||
		tmpSourcePath, "make KERNEL="+kernel+" TARGET="+target)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		err = errors.New("make execution error")
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								pew_test.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								pew_test.go
									
									
									
									
									
								
							@@ -13,7 +13,7 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestDockerCommand(t *testing.T) {
 | 
			
		||||
func TestDockerRun(t *testing.T) {
 | 
			
		||||
	tmp, err := ioutil.TempDir("/tmp/", "out-of-tree_test_")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
@@ -22,8 +22,9 @@ func TestDockerCommand(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	start := time.Now()
 | 
			
		||||
 | 
			
		||||
	c := dockerCommand("ubuntu", tmp, "1s", "sleep 5s")
 | 
			
		||||
	_, err = c.CombinedOutput()
 | 
			
		||||
	timeout := time.Second
 | 
			
		||||
 | 
			
		||||
	_, err = dockerRun(timeout, "ubuntu", tmp, "sleep 5s")
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Fatal("docker is not killed by timeout")
 | 
			
		||||
	}
 | 
			
		||||
@@ -32,13 +33,12 @@ func TestDockerCommand(t *testing.T) {
 | 
			
		||||
			time.Since(start), time.Second))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = dockerCommand("ubuntu", tmp, "1m", "echo hello")
 | 
			
		||||
	rawOutput, err := c.CombinedOutput()
 | 
			
		||||
	output, err := dockerRun(time.Minute, "ubuntu", tmp, "echo hello")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !strings.Contains(string(rawOutput), "hello") {
 | 
			
		||||
		t.Fatal("wrong output (" + string(rawOutput) + ")")
 | 
			
		||||
	if !strings.Contains(output, "hello") {
 | 
			
		||||
		t.Fatal("wrong output (" + output + ")")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		新增問題並參考
	
	封鎖使用者