From 2b1158f4c26f39762e466003022ef30cc20f4804 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Fri, 26 Mar 2021 17:46:19 +0100 Subject: [PATCH] Adapt cli/mobycli to avoid duplicating shellout code Signed-off-by: Guillaume Tardif --- cli/mobycli/exec.go | 61 ++++++++++++++++++++----------------- local/compose/build_win.go | 7 +++-- local/moby/exec.go | 62 -------------------------------------- 3 files changed, 38 insertions(+), 92 deletions(-) delete mode 100644 local/moby/exec.go diff --git a/cli/mobycli/exec.go b/cli/mobycli/exec.go index dbafd79f..6a5e09dd 100644 --- a/cli/mobycli/exec.go +++ b/cli/mobycli/exec.go @@ -62,35 +62,8 @@ func mustDelegateToMoby(ctxType string) bool { // Exec delegates to com.docker.cli if on moby context func Exec(root *cobra.Command) { - execBinary, err := resolvepath.LookPath(ComDockerCli) - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - cmd := exec.Command(execBinary, os.Args[1:]...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - signals := make(chan os.Signal, 1) childExit := make(chan bool) - signal.Notify(signals) // catch all signals - go func() { - for { - select { - case sig := <-signals: - if cmd.Process == nil { - continue // can happen if receiving signal before the process is actually started - } - // nolint errcheck - cmd.Process.Signal(sig) - case <-childExit: - return - } - } - }() - - err = cmd.Run() + err := RunDocker(childExit, os.Args[1:]...) childExit <- true if err != nil { metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus) @@ -110,6 +83,38 @@ func Exec(root *cobra.Command) { os.Exit(0) } +// RunDocker runs a docker command, and forward signals to the shellout command (stops listening to signals when an event is sent to childExit) +func RunDocker(childExit chan bool, args ...string) error { + execBinary, err := resolvepath.LookPath(ComDockerCli) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + cmd := exec.Command(execBinary, args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + signals := make(chan os.Signal, 1) + signal.Notify(signals) // catch all signals + go func() { + for { + select { + case sig := <-signals: + if cmd.Process == nil { + continue // can happen if receiving signal before the process is actually started + } + // nolint errcheck + cmd.Process.Signal(sig) + case <-childExit: + return + } + } + }() + + return cmd.Run() +} + // IsDefaultContextCommand checks if the command exists in the classic cli (issues a shellout --help) func IsDefaultContextCommand(dockerCommand string) bool { cmd := exec.Command(ComDockerCli, dockerCommand, "--help") diff --git a/local/compose/build_win.go b/local/compose/build_win.go index a05fa7c2..431eeed0 100644 --- a/local/compose/build_win.go +++ b/local/compose/build_win.go @@ -22,7 +22,7 @@ import ( "path/filepath" "github.com/docker/compose-cli/api/compose" - "github.com/docker/compose-cli/local/moby" + "github.com/docker/compose-cli/cli/mobycli" "github.com/compose-spec/compose-go/types" ) @@ -60,7 +60,10 @@ func (s *composeService) windowsBuild(project *types.Project, options compose.Bu args := cmd.getArguments() // shell out to moby cli - err := moby.Exec(args) + childExit := make(chan bool) + err := mobycli.RunDocker(childExit, args...) + childExit <- true + if err != nil { return err } diff --git a/local/moby/exec.go b/local/moby/exec.go deleted file mode 100644 index 97ee4377..00000000 --- a/local/moby/exec.go +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright 2020 Docker Compose CLI authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package moby - -import ( - "os" - "os/exec" - "os/signal" - - "github.com/docker/compose-cli/cli/mobycli/resolvepath" -) - -// ComDockerCli name of the classic cli binary -const ComDockerCli = "com.docker.cli" - -// Exec delegates to com.docker.cli -func Exec(args []string) error { - // look up the path of the classic cli binary - execBinary, err := resolvepath.LookPath(ComDockerCli) - if err != nil { - return err - } - cmd := exec.Command(execBinary, args...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - - signals := make(chan os.Signal, 1) - childExit := make(chan bool) - signal.Notify(signals) // catch all signals - go func() { - for { - select { - case sig := <-signals: - if cmd.Process == nil { - continue // can happen if receiving signal before the process is actually started - } - // nolint errcheck - cmd.Process.Signal(sig) - case <-childExit: - return - } - } - }() - err = cmd.Run() - childExit <- true - return err -}