Skip to content

Commit

Permalink
Refactor kube exec to support io streams (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdmanv committed Sep 4, 2019
1 parent 42d113d commit e5dfd1e
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions pkg/kube/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
package kube

import (
"bytes"
"io"
"io/ioutil"
"net/url"
"strings"

log "github.com/sirupsen/logrus"
"k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
Expand Down Expand Up @@ -59,6 +59,26 @@ func Exec(cli kubernetes.Interface, namespace, pod, container string, command []
// returning stdout, stderr and error. `options` allowed for
// additional parameters to be passed.
func ExecWithOptions(kubeCli kubernetes.Interface, options ExecOptions) (string, string, error) {
config, err := LoadConfig()
if err != nil {
return "", "", err
}
o, e, errCh := execStream(kubeCli, config, options)
defer func() { _ = o.Close() }()
defer func() { _ = e.Close() }()
stdout, oerr := ioutil.ReadAll(o)
if oerr != nil {
log.Info("Failed to read stdout:", oerr.Error())
}
stderr, eerr := ioutil.ReadAll(e)
if eerr != nil {
log.Info("Failed to read stderr:", eerr.Error())
}

return string(stdout), string(stderr), <-errCh
}

func execStream(kubeCli kubernetes.Interface, config *restclient.Config, options ExecOptions) (io.ReadCloser, io.ReadCloser, chan error) {
const tty = false
req := kubeCli.CoreV1().RESTClient().Post().
Resource("pods").
Expand All @@ -78,14 +98,16 @@ func ExecWithOptions(kubeCli kubernetes.Interface, options ExecOptions) (string,
TTY: tty,
}, scheme.ParameterCodec)

config, err := LoadConfig()
if err != nil {
return "", "", err
}

var stdout, stderr bytes.Buffer
err = execute("POST", req.URL(), config, options.Stdin, &stdout, &stderr, tty)
return strings.TrimSpace(stdout.String()), strings.TrimSpace(stderr.String()), err
pro, pwo := io.Pipe()
pre, pwe := io.Pipe()
errCh := make(chan error, 1)
go func() {
err := execute("POST", req.URL(), config, options.Stdin, pwo, pwe, tty)
errCh <- err
_ = pwo.Close()
_ = pwe.Close()
}()
return pro, pre, errCh
}

func execute(method string, url *url.URL, config *restclient.Config, stdin io.Reader, stdout, stderr io.Writer, tty bool) error {
Expand Down

0 comments on commit e5dfd1e

Please sign in to comment.