From ef66f1ead85d2b0dd47a5a4fe14dc57d55300744 Mon Sep 17 00:00:00 2001 From: Jing Liu Date: Thu, 16 Jun 2016 12:19:34 -0700 Subject: [PATCH] improve iptables-restore implementation #27559 - improve restoreInternal implementation in iptables - add SetStdin and SetStdout functions to Cmd interface - modify kubelet/prober and some tests in order to work with Cmd interface --- pkg/kubelet/prober/prober.go | 9 +++++++++ pkg/probe/exec/exec_test.go | 5 +++++ pkg/util/exec/exec.go | 11 +++++++++++ pkg/util/exec/fake_exec.go | 11 +++++++++++ pkg/util/iptables/iptables.go | 30 ++++++------------------------ 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/pkg/kubelet/prober/prober.go b/pkg/kubelet/prober/prober.go index 82d2eb5468..9a37bc8fed 100644 --- a/pkg/kubelet/prober/prober.go +++ b/pkg/kubelet/prober/prober.go @@ -19,6 +19,7 @@ package prober import ( "bytes" "fmt" + "io" "net" "net/http" "net/url" @@ -248,3 +249,11 @@ func (eic execInContainer) Output() ([]byte, error) { func (eic execInContainer) SetDir(dir string) { //unimplemented } + +func (eic execInContainer) SetStdin(in io.Reader) { + //unimplemented +} + +func (eic execInContainer) SetStdout(out io.Writer) { + //unimplemented +} diff --git a/pkg/probe/exec/exec_test.go b/pkg/probe/exec/exec_test.go index 6c01871dd9..3e3aec284f 100644 --- a/pkg/probe/exec/exec_test.go +++ b/pkg/probe/exec/exec_test.go @@ -18,6 +18,7 @@ package exec import ( "fmt" + "io" "testing" "k8s.io/kubernetes/pkg/probe" @@ -39,6 +40,10 @@ func (f *FakeCmd) Output() ([]byte, error) { func (f *FakeCmd) SetDir(dir string) {} +func (f *FakeCmd) SetStdin(in io.Reader) {} + +func (f *FakeCmd) SetStdout(out io.Writer) {} + type fakeExitError struct { exited bool statusCode int diff --git a/pkg/util/exec/exec.go b/pkg/util/exec/exec.go index 80444a9d86..d18c0b89b9 100644 --- a/pkg/util/exec/exec.go +++ b/pkg/util/exec/exec.go @@ -17,6 +17,7 @@ limitations under the License. package exec import ( + "io" osexec "os/exec" "syscall" ) @@ -45,6 +46,8 @@ type Cmd interface { // Output runs the command and returns standard output, but not standard err Output() ([]byte, error) SetDir(dir string) + SetStdin(in io.Reader) + SetStdout(out io.Writer) } // ExitError is an interface that presents an API similar to os.ProcessState, which is @@ -82,6 +85,14 @@ func (cmd *cmdWrapper) SetDir(dir string) { cmd.Dir = dir } +func (cmd *cmdWrapper) SetStdin(in io.Reader) { + cmd.Stdin = in +} + +func (cmd *cmdWrapper) SetStdout(out io.Writer) { + cmd.Stdout = out +} + // CombinedOutput is part of the Cmd interface. func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { out, err := (*osexec.Cmd)(cmd).CombinedOutput() diff --git a/pkg/util/exec/fake_exec.go b/pkg/util/exec/fake_exec.go index 40df52921b..faee16c014 100644 --- a/pkg/util/exec/fake_exec.go +++ b/pkg/util/exec/fake_exec.go @@ -18,6 +18,7 @@ package exec import ( "fmt" + "io" ) // A simple scripted Interface type. @@ -49,6 +50,8 @@ type FakeCmd struct { CombinedOutputCalls int CombinedOutputLog [][]string Dirs []string + Stdin io.Reader + Stdout io.Writer } func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) Cmd { @@ -62,6 +65,14 @@ func (fake *FakeCmd) SetDir(dir string) { fake.Dirs = append(fake.Dirs, dir) } +func (fake *FakeCmd) SetStdin(in io.Reader) { + fake.Stdin = in +} + +func (fake *FakeCmd) SetStdout(out io.Writer) { + fake.Stdout = out +} + func (fake *FakeCmd) CombinedOutput() ([]byte, error) { if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 { panic("ran out of CombinedOutput() actions") diff --git a/pkg/util/iptables/iptables.go b/pkg/util/iptables/iptables.go index 801cc8bf72..197d861251 100644 --- a/pkg/util/iptables/iptables.go +++ b/pkg/util/iptables/iptables.go @@ -17,9 +17,8 @@ limitations under the License. package iptables import ( + "bytes" "fmt" - "io/ioutil" - "os" "regexp" "strings" "sync" @@ -60,7 +59,7 @@ type Interface interface { Save(table Table) ([]byte, error) // SaveAll calls `iptables-save`. SaveAll() ([]byte, error) - // Restore runs `iptables-restore` passing data through a temporary file. + // Restore runs `iptables-restore` passing data through []byte. // table is the Table to restore // data should be formatted like the output of Save() // flush sets the presence of the "--noflush" flag. see: FlushFlag @@ -335,29 +334,12 @@ func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFla if counters { args = append(args, "--counters") } - // create temp file through which to pass data - temp, err := ioutil.TempFile("", "kube-temp-iptables-restore-") - if err != nil { - return err - } - // make sure we delete the temp file - defer os.Remove(temp.Name()) - // Put the filename at the end of args. - // NOTE: the filename must be at the end. - // See: https://git.netfilter.org/iptables/commit/iptables-restore.c?id=e6869a8f59d779ff4d5a0984c86d80db70784962 - args = append(args, temp.Name()) - if err != nil { - return err - } - // write data to the file - _, err = temp.Write(data) - temp.Close() - if err != nil { - return err - } + // run the command and return the output or an error including the output and error glog.V(4).Infof("running iptables-restore %v", args) - b, err := runner.exec.Command(cmdIptablesRestore, args...).CombinedOutput() + cmd := runner.exec.Command(cmdIptablesRestore, args...) + cmd.SetStdin(bytes.NewBuffer(data)) + b, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("%v (%s)", err, b) }