Merge pull request #335 from tonistiigi/git-cancellation
git: fix cancellation on blocking remotesdocker-18.09
commit
ef8e683ffa
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
Loading…
Reference in New Issue