/
exec.go
74 lines (63 loc) · 1.65 KB
/
exec.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package backend
import (
"context"
"io"
"strconv"
"strings"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/joyrex2001/kubedock/internal/model/types"
"github.com/joyrex2001/kubedock/internal/util/exec"
"github.com/joyrex2001/kubedock/internal/util/ioproxy"
)
// ExecContainer will execute given exec object in kubernetes.
func (in *instance) ExecContainer(tainr *types.Container, ex *types.Exec, stdin io.Reader, stdout io.Writer) (int, error) {
pod, err := in.cli.CoreV1().Pods(in.namespace).Get(context.Background(), tainr.GetPodName(), metav1.GetOptions{})
if err != nil {
return 0, err
}
req := exec.Request{
Client: in.cli,
RestConfig: in.cfg,
Pod: *pod,
Container: "main",
Cmd: ex.Cmd,
TTY: ex.TTY,
}
if ex.Stdin {
req.Stdin = stdin
}
if ex.TTY {
req.Stdout = stdout
req.Stderr = io.Discard
} else {
if ex.Stdout {
iop := ioproxy.New(stdout, ioproxy.Stdout)
req.Stdout = iop
defer iop.Flush()
}
if ex.Stderr {
iop := ioproxy.New(stdout, ioproxy.Stderr)
req.Stderr = iop
defer iop.Flush()
}
}
err = exec.RemoteCmd(req)
return in.parseExecResponse(err)
}
// parseExecResponse will take the given error and will parse the string to
// get an exit code from it. if no exit code is found, it will return 0 and
// the original error.
func (in *instance) parseExecResponse(err error) (int, error) {
if err == nil {
return 0, err
}
const eterm = "command terminated with exit code"
if !strings.Contains(err.Error(), eterm) {
return 0, err
}
cod, cerr := strconv.Atoi(strings.TrimPrefix(err.Error(), eterm+" "))
if cerr != nil {
return 0, err
}
return cod, nil
}