mirror of https://github.com/docker/compose.git
Forward closing signal to docker-classic when closing docker. Note this will not forward Kill signal, impossible to intercept / process this one.
This commit is contained in:
parent
e630ace677
commit
cc46f84043
|
@ -186,7 +186,7 @@ func execMoby(ctx context.Context) {
|
||||||
// Only run original docker command if the current context is not
|
// Only run original docker command if the current context is not
|
||||||
// ours.
|
// ours.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd := exec.Command("docker-classic", os.Args[1:]...)
|
cmd := exec.CommandContext(ctx,"docker-classic", os.Args[1:]...)
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
|
@ -29,17 +29,19 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gotest.tools/golden"
|
"gotest.tools/golden"
|
||||||
|
|
||||||
. "github.com/onsi/gomega"
|
|
||||||
"github.com/stretchr/testify/suite"
|
|
||||||
|
|
||||||
. "github.com/docker/api/tests/framework"
|
. "github.com/docker/api/tests/framework"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,6 +81,37 @@ func (s *E2eSuite) TestSetupError() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *E2eSuite) TestKillChildOnCancel() {
|
||||||
|
It("should kill docker-classic if parent command is cancelled", func() {
|
||||||
|
out := s.NewCommand("ps", "-x").ExecOrDie()
|
||||||
|
Expect(out).NotTo(ContainSubstring("docker-classic"))
|
||||||
|
|
||||||
|
dir := s.ConfigDir
|
||||||
|
Expect(ioutil.WriteFile(filepath.Join(dir, "Dockerfile"), []byte(`FROM alpine:3.10
|
||||||
|
RUN sleep 100`), 0644)).To(Succeed())
|
||||||
|
shutdown := make(chan time.Time)
|
||||||
|
errs := make(chan error)
|
||||||
|
ctx := s.NewDockerCommand("build", "--no-cache", "-t", "test-sleep-image", ".").WithinDirectory(dir).WithTimeout(shutdown)
|
||||||
|
go func() {
|
||||||
|
_, err := ctx.Exec()
|
||||||
|
errs <- err
|
||||||
|
}()
|
||||||
|
err := WaitFor(time.Second, 3*time.Second, errs, func() bool {
|
||||||
|
out := s.NewCommand("ps", "-x").ExecOrDie()
|
||||||
|
return strings.Contains(out, "docker-classic")
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
log.Println("Killing docker process")
|
||||||
|
|
||||||
|
close(shutdown)
|
||||||
|
err = WaitFor(time.Second, 4*time.Second, nil, func() bool {
|
||||||
|
out := s.NewCommand("ps", "-x").ExecOrDie()
|
||||||
|
return !strings.Contains(out, "docker-classic")
|
||||||
|
})
|
||||||
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (s *E2eSuite) TestLegacy() {
|
func (s *E2eSuite) TestLegacy() {
|
||||||
It("should list all legacy commands", func() {
|
It("should list all legacy commands", func() {
|
||||||
output := s.NewDockerCommand("--help").ExecOrDie()
|
output := s.NewDockerCommand("--help").ExecOrDie()
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsi/gomega"
|
"github.com/onsi/gomega"
|
||||||
|
@ -129,6 +130,29 @@ func (b CmdContext) Exec() (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//WaitFor waits for a condition to be true
|
||||||
|
func WaitFor(interval, duration time.Duration, abort <-chan error, condition func() bool) error {
|
||||||
|
ticker := time.NewTicker(interval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
timeout := make(chan int)
|
||||||
|
go func() {
|
||||||
|
time.Sleep(duration)
|
||||||
|
close(timeout)
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case err := <-abort:
|
||||||
|
return err
|
||||||
|
case <-timeout:
|
||||||
|
return fmt.Errorf("timeout after %v", duration)
|
||||||
|
case <-ticker.C:
|
||||||
|
if condition() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Execute executes a command.
|
// Execute executes a command.
|
||||||
// The command cannot be re-used afterwards.
|
// The command cannot be re-used afterwards.
|
||||||
func Execute(cmd *exec.Cmd, timeout <-chan time.Time) (string, error) {
|
func Execute(cmd *exec.Cmd, timeout <-chan time.Time) (string, error) {
|
||||||
|
@ -152,7 +176,7 @@ func Execute(cmd *exec.Cmd, timeout <-chan time.Time) (string, error) {
|
||||||
}
|
}
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
log.Debugf("%s %s timed-out", cmd.Path, strings.Join(cmd.Args[1:], " "))
|
log.Debugf("%s %s timed-out", cmd.Path, strings.Join(cmd.Args[1:], " "))
|
||||||
if err := cmd.Process.Kill(); err != nil {
|
if err := cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf(
|
return "", fmt.Errorf(
|
||||||
|
|
Loading…
Reference in New Issue