Exec probes should not be unbounded

In 1f270ef4e2, we added 10KB as the read
limit for http probes. we should do the same for exec probes as well.

Change-Id: If154c5c4e669829ab94839c56260a894a6714f0f
This commit is contained in:
Davanum Srinivas
2019-09-09 23:12:07 -04:00
parent 1b79c1f6b3
commit 5706a13bd6
7 changed files with 119 additions and 46 deletions

View File

@@ -11,6 +11,7 @@ go_library(
srcs = ["exec.go"],
importpath = "k8s.io/kubernetes/pkg/probe/exec",
deps = [
"//pkg/kubelet/util/ioutils:go_default_library",
"//pkg/probe:go_default_library",
"//vendor/k8s.io/klog:go_default_library",
"//vendor/k8s.io/utils/exec:go_default_library",

View File

@@ -17,10 +17,17 @@ limitations under the License.
package exec
import (
"bytes"
"k8s.io/kubernetes/pkg/kubelet/util/ioutils"
"k8s.io/kubernetes/pkg/probe"
"k8s.io/utils/exec"
"k8s.io/klog"
"k8s.io/utils/exec"
)
const (
maxReadLength = 10 * 1 << 10 // 10KB
)
// New creates a Prober.
@@ -39,7 +46,17 @@ type execProber struct{}
// from executing a command. Returns the Result status, command output, and
// errors if any.
func (pr execProber) Probe(e exec.Cmd) (probe.Result, string, error) {
data, err := e.CombinedOutput()
var dataBuffer bytes.Buffer
writer := ioutils.LimitWriter(&dataBuffer, maxReadLength)
e.SetStderr(writer)
e.SetStdout(writer)
err := e.Start()
if err == nil {
err = e.Wait()
}
data := dataBuffer.Bytes()
klog.V(4).Infof("Exec probe response: %q", string(data))
if err != nil {
exit, ok := err.(exec.ExitError)

View File

@@ -19,6 +19,7 @@ package exec
import (
"fmt"
"io"
"strings"
"testing"
"k8s.io/kubernetes/pkg/probe"
@@ -28,6 +29,7 @@ type FakeCmd struct {
out []byte
stdout []byte
err error
writer io.Writer
}
func (f *FakeCmd) Run() error {
@@ -46,15 +48,25 @@ func (f *FakeCmd) SetDir(dir string) {}
func (f *FakeCmd) SetStdin(in io.Reader) {}
func (f *FakeCmd) SetStdout(out io.Writer) {}
func (f *FakeCmd) SetStdout(out io.Writer) {
f.writer = out
}
func (f *FakeCmd) SetStderr(out io.Writer) {}
func (f *FakeCmd) SetStderr(out io.Writer) {
f.writer = out
}
func (f *FakeCmd) SetEnv(env []string) {}
func (f *FakeCmd) Stop() {}
func (f *FakeCmd) Start() error { return nil }
func (f *FakeCmd) Start() error {
if f.writer != nil {
f.writer.Write(f.out)
return f.err
}
return f.err
}
func (f *FakeCmd) Wait() error { return nil }
@@ -90,20 +102,26 @@ func (f *fakeExitError) ExitStatus() int {
func TestExec(t *testing.T) {
prober := New()
tenKilobyte := strings.Repeat("logs-123", 128*10) // 8*128*10=10240 = 10KB of text.
elevenKilobyte := strings.Repeat("logs-123", 8*128*11) // 8*128*11=11264 = 11KB of text.
tests := []struct {
expectedStatus probe.Result
expectError bool
input string
output string
err error
}{
// Ok
{probe.Success, false, "OK", nil},
{probe.Success, false, "OK", "OK", nil},
// Ok
{probe.Success, false, "OK", &fakeExitError{true, 0}},
{probe.Success, false, "OK", "OK", &fakeExitError{true, 0}},
// Ok - truncated output
{probe.Success, false, elevenKilobyte, tenKilobyte, nil},
// Run returns error
{probe.Unknown, true, "", fmt.Errorf("test error")},
{probe.Unknown, true, "", "", fmt.Errorf("test error")},
// Unhealthy
{probe.Failure, false, "Fail", &fakeExitError{true, 1}},
{probe.Failure, false, "Fail", "", &fakeExitError{true, 1}},
}
for i, test := range tests {
fake := FakeCmd{