func (*DefaultRemoteExecutor) Execute(req *client.Request, config *client.Config, command []string, stdin io.Reader, stdout, stderr io.Writer, tty bool) error { executor := remotecommand.New(req, config, command, stdin, stdout, stderr, tty) return executor.Execute() }
func RunExec(f *Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.Command, args []string) error { podName := util.GetFlagString(cmd, "pod") if len(podName) == 0 { return util.UsageError(cmd, "POD is required for exec") } if len(args) < 1 { return util.UsageError(cmd, "COMMAND is required for exec") } namespace, err := f.DefaultNamespace() if err != nil { return err } client, err := f.Client() if err != nil { return err } pod, err := client.Pods(namespace).Get(podName) if err != nil { return err } if pod.Status.Phase != api.PodRunning { glog.Fatalf("Unable to execute command because pod is not running. Current status=%v", pod.Status.Phase) } containerName := util.GetFlagString(cmd, "container") if len(containerName) == 0 { containerName = pod.Spec.Containers[0].Name } var stdin io.Reader tty := util.GetFlagBool(cmd, "tty") if util.GetFlagBool(cmd, "stdin") { stdin = cmdIn if tty { if file, ok := cmdIn.(*os.File); ok { inFd := file.Fd() if term.IsTerminal(inFd) { oldState, err := term.SetRawTerminal(inFd) if err != nil { glog.Fatal(err) } // this handles a clean exit, where the command finished defer term.RestoreTerminal(inFd, oldState) // SIGINT is handled by term.SetRawTerminal (it runs a goroutine that listens // for SIGINT and restores the terminal before exiting) // this handles SIGTERM sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGTERM) go func() { <-sigChan term.RestoreTerminal(inFd, oldState) os.Exit(0) }() } else { glog.Warning("Stdin is not a terminal") } } else { tty = false glog.Warning("Unable to use a TTY") } } } config, err := f.ClientConfig() if err != nil { return err } req := client.RESTClient.Get(). Prefix("proxy"). Resource("minions"). Name(pod.Status.Host). Suffix("exec", namespace, podName, containerName) e := remotecommand.New(req, config, args, stdin, cmdOut, cmdErr, tty) return e.Execute() }