From 866bd7b4e5273c3c1be2031f205f2cf47d707a74 Mon Sep 17 00:00:00 2001 From: Marcin Wielgus Date: Wed, 15 Jul 2015 14:10:47 +0200 Subject: [PATCH] Dump stdin to a temporary file in kubectl replace --force --- pkg/kubectl/cmd/replace.go | 18 ++++++++++++++++++ pkg/kubectl/cmd/util/helpers.go | 25 +++++++++++++++++++++++++ pkg/kubectl/cmd/util/helpers_test.go | 23 +++++++++++++++++++++++ pkg/kubectl/resource/builder.go | 2 +- 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index 6efc88ec47f..793f445790f 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -19,7 +19,9 @@ package cmd import ( "fmt" "io" + "io/ioutil" "os" + "path/filepath" "github.com/spf13/cobra" @@ -131,6 +133,22 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args [] return err } + for i, filename := range filenames { + if filename == "-" { + tempDir, err := ioutil.TempDir("", "kubectl_replace_") + if err != nil { + return err + } + defer os.RemoveAll(tempDir) + tempFilename := filepath.Join(tempDir, "resource.stdin") + err = cmdutil.DumpReaderToFile(os.Stdin, tempFilename) + if err != nil { + return err + } + filenames[i] = tempFilename + } + } + mapper, typer := f.Object() r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()). ContinueOnError(). diff --git a/pkg/kubectl/cmd/util/helpers.go b/pkg/kubectl/cmd/util/helpers.go index c91138525bb..a0e21af7230 100644 --- a/pkg/kubectl/cmd/util/helpers.go +++ b/pkg/kubectl/cmd/util/helpers.go @@ -406,3 +406,28 @@ func Merge(dst runtime.Object, fragment, kind string) (runtime.Object, error) { } return out, nil } + +// DumpReaderToFile writes all data from the given io.Reader to the specified file +// (usually for temporary use). +func DumpReaderToFile(reader io.Reader, filename string) error { + f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + defer f.Close() + if err != nil { + return err + } + buffer := make([]byte, 1024) + for { + count, err := reader.Read(buffer) + if err == io.EOF { + break + } + if err != nil { + return err + } + _, err = f.Write(buffer[:count]) + if err != nil { + return err + } + } + return nil +} diff --git a/pkg/kubectl/cmd/util/helpers_test.go b/pkg/kubectl/cmd/util/helpers_test.go index 5b335a068de..57d0999e3c6 100644 --- a/pkg/kubectl/cmd/util/helpers_test.go +++ b/pkg/kubectl/cmd/util/helpers_test.go @@ -22,6 +22,7 @@ import ( "net/http" "net/http/httptest" "reflect" + "strings" "syscall" "testing" @@ -298,3 +299,25 @@ func TestCheckInvalidErr(t *testing.T) { } } } + +func TestDumpReaderToFile(t *testing.T) { + testString := "TEST STRING" + tempFile, err := ioutil.TempFile("", "hlpers_test_dump_") + if err != nil { + t.Errorf("unexpected error setting up a temporary file %v", err) + } + defer syscall.Unlink(tempFile.Name()) + defer tempFile.Close() + err = DumpReaderToFile(strings.NewReader(testString), tempFile.Name()) + if err != nil { + t.Errorf("error in DumpReaderToFile: %v", err) + } + data, err := ioutil.ReadFile(tempFile.Name()) + if err != nil { + t.Errorf("error when reading %s: %v", tempFile, err) + } + stringData := string(data) + if stringData != testString { + t.Fatalf("Wrong file content %s != %s", testString, stringData) + } +} diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index 9895ed1494e..207ce57c303 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -164,7 +164,7 @@ func (b *Builder) Path(paths ...string) *Builder { continue } - visitors, err := ExpandPathsToFileVisitors(b.mapper, p, false, []string{".json", ".yaml", ".yml"}, b.continueOnError, b.schema) + visitors, err := ExpandPathsToFileVisitors(b.mapper, p, false, []string{".json", ".stdin", ".yaml", ".yml"}, b.continueOnError, b.schema) if err != nil { b.errs = append(b.errs, fmt.Errorf("error reading %q: %v", p, err)) }