Merge pull request #335 from tonistiigi/git-cancellation

git: fix cancellation on blocking remotes
docker-18.09
Akihiro Suda 2018-04-11 14:06:50 +09:00 committed by GitHub
commit ef8e683ffa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 2 deletions

View File

@ -374,13 +374,15 @@ func git(ctx context.Context, dir string, args ...string) (*bytes.Buffer, error)
stdout, stderr := logs.NewLogStreams(ctx)
defer stdout.Close()
defer stderr.Close()
cmd := exec.CommandContext(ctx, "git", args...)
cmd := exec.Command("git", args...)
cmd.Dir = dir // some commands like submodule require this
buf := bytes.NewBuffer(nil)
errbuf := bytes.NewBuffer(nil)
cmd.Stdout = io.MultiWriter(stdout, buf)
cmd.Stderr = io.MultiWriter(stderr, errbuf)
err := cmd.Run()
// remote git commands spawn helper processes that inherit FDs and don't
// handle parent death signal so exec.CommandContext can't be used
err := runProcessGroup(ctx, cmd)
if err != nil {
if strings.Contains(errbuf.String(), "--depth") || strings.Contains(errbuf.String(), "shallow") {
if newArgs := argsNoDepth(args); len(args) > len(newArgs) {

View File

@ -0,0 +1,27 @@
// +build !windows
package git
import (
"context"
"os/exec"
"syscall"
)
func runProcessGroup(ctx context.Context, cmd *exec.Cmd) error {
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
if err := cmd.Start(); err != nil {
return err
}
waitDone := make(chan struct{})
go func() {
select {
case <-ctx.Done():
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
case <-waitDone:
}
}()
err := cmd.Wait()
close(waitDone)
return err
}

View File

@ -0,0 +1,23 @@
// +build windows
package git
import (
"context"
"os/exec"
)
func runProcessGroup(ctx context.Context, cmd *exec.Cmd) error {
if err := cmd.Start(); err != nil {
return err
}
waitDone := make(chan struct{})
go func() {
select {
case <-ctx.Done():
cmd.Process.Kill()
case <-waitDone:
}
}()
return cmd.Wait()
}