exec.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package mobycli
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "strings"
  8. "github.com/spf13/cobra"
  9. apicontext "github.com/docker/api/context"
  10. "github.com/docker/api/context/store"
  11. )
  12. // ComDockerCli name of the classic cli binary
  13. const ComDockerCli = "com.docker.cli"
  14. // Exec delegates to com.docker.cli
  15. func Exec(ctx context.Context) {
  16. currentContext := apicontext.CurrentContext(ctx)
  17. s := store.ContextStore(ctx)
  18. _, err := s.Get(currentContext)
  19. // Only run original docker command if the current context is not
  20. // ours.
  21. if err != nil {
  22. cmd := exec.CommandContext(ctx, ComDockerCli, os.Args[1:]...)
  23. cmd.Stdin = os.Stdin
  24. cmd.Stdout = os.Stdout
  25. cmd.Stderr = os.Stderr
  26. if err := cmd.Run(); err != nil {
  27. if exiterr, ok := err.(*exec.ExitError); ok {
  28. os.Exit(exiterr.ExitCode())
  29. }
  30. fmt.Fprintln(os.Stderr, err)
  31. os.Exit(1)
  32. }
  33. os.Exit(0)
  34. }
  35. }
  36. // ExecCmd delegates the cli command to com.docker.cli. The error is never returned (process will exit with docker classic exit code), the return type is to make it easier to use with cobra commands
  37. func ExecCmd(command *cobra.Command) error {
  38. Exec(command.Context())
  39. return nil
  40. }
  41. // IsDefaultContextCommand checks if the command exists in the classic cli (issues a shellout --help)
  42. func IsDefaultContextCommand(dockerCommand string) bool {
  43. cmd := exec.Command(ComDockerCli, dockerCommand, "--help")
  44. b, e := cmd.CombinedOutput()
  45. if e != nil {
  46. fmt.Println(e)
  47. }
  48. output := string(b)
  49. contains := strings.Contains(output, "Usage:\tdocker "+dockerCommand)
  50. return contains
  51. }
  52. // ExecSilent executes a command and do redirect output to stdOut, return output
  53. func ExecSilent(ctx context.Context) ([]byte, error) {
  54. cmd := exec.CommandContext(ctx, ComDockerCli, os.Args[1:]...)
  55. return cmd.CombinedOutput()
  56. }