mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #63536 from deads2k/cli-51-streams
Automatic merge from submit-queue (batch tested with PRs 63070, 63536). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. use IOStreams for cli commands Scrubs the last commands to use IOStreams for consistency and testability. @kubernetes/sig-cli-maintainers /assign @juanvallejo ```release-note NONE ```
This commit is contained in:
commit
a67ccaeab1
@ -17,17 +17,16 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdAlpha creates a command that acts as an alternate root command for features in alpha
|
// NewCmdAlpha creates a command that acts as an alternate root command for features in alpha
|
||||||
func NewCmdAlpha(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
|
func NewCmdAlpha(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "alpha",
|
Use: "alpha",
|
||||||
Short: i18n.T("Commands for features in alpha"),
|
Short: i18n.T("Commands for features in alpha"),
|
||||||
@ -37,7 +36,7 @@ func NewCmdAlpha(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Com
|
|||||||
// Alpha commands should be added here. As features graduate from alpha they should move
|
// Alpha commands should be added here. As features graduate from alpha they should move
|
||||||
// from here to the CommandGroups defined by NewKubeletCommand() in cmd.go.
|
// from here to the CommandGroups defined by NewKubeletCommand() in cmd.go.
|
||||||
//cmd.AddCommand(NewCmdDebug(f, in, out, err))
|
//cmd.AddCommand(NewCmdDebug(f, in, out, err))
|
||||||
cmd.AddCommand(NewCmdDiff(f, out, err))
|
cmd.AddCommand(NewCmdDiff(f, streams))
|
||||||
|
|
||||||
// NewKubeletCommand() will hide the alpha command if it has no subcommands. Overriding
|
// NewKubeletCommand() will hide the alpha command if it has no subcommands. Overriding
|
||||||
// the help function ensures a reasonable message if someone types the hidden command anyway.
|
// the help function ensures a reasonable message if someone types the hidden command anyway.
|
||||||
|
@ -197,7 +197,7 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
o.DeleteOptions = o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
o.DeleteOptions = o.DeleteFlags.ToOptions(o.IOStreams)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -60,12 +61,10 @@ const (
|
|||||||
defaultPodLogsTimeout = 20 * time.Second
|
defaultPodLogsTimeout = 20 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
|
func NewCmdAttach(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
options := &AttachOptions{
|
o := &AttachOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
In: cmdIn,
|
IOStreams: streams,
|
||||||
Out: cmdOut,
|
|
||||||
Err: cmdErr,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Attach: &DefaultRemoteAttach{},
|
Attach: &DefaultRemoteAttach{},
|
||||||
@ -77,15 +76,15 @@ func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer)
|
|||||||
Long: "Attach to a process that is already running inside an existing container.",
|
Long: "Attach to a process that is already running inside an existing container.",
|
||||||
Example: attachExample,
|
Example: attachExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(options.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
cmdutil.CheckErr(options.Run())
|
cmdutil.CheckErr(o.Run())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodAttachTimeout)
|
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodAttachTimeout)
|
||||||
cmd.Flags().StringVarP(&options.ContainerName, "container", "c", options.ContainerName, "Container name. If omitted, the first container in the pod will be chosen")
|
cmd.Flags().StringVarP(&o.ContainerName, "container", "c", o.ContainerName, "Container name. If omitted, the first container in the pod will be chosen")
|
||||||
cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", options.Stdin, "Pass stdin to the container")
|
cmd.Flags().BoolVarP(&o.Stdin, "stdin", "i", o.Stdin, "Pass stdin to the container")
|
||||||
cmd.Flags().BoolVarP(&options.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
|
cmd.Flags().BoolVarP(&o.TTY, "tty", "t", o.TTY, "Stdin is a TTY")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +202,7 @@ func (p *AttachOptions) Validate() error {
|
|||||||
if len(p.PodName) == 0 {
|
if len(p.PodName) == 0 {
|
||||||
allErrs = append(allErrs, errors.New("pod name must be specified"))
|
allErrs = append(allErrs, errors.New("pod name must be specified"))
|
||||||
}
|
}
|
||||||
if p.Out == nil || p.Err == nil {
|
if p.Out == nil || p.ErrOut == nil {
|
||||||
allErrs = append(allErrs, errors.New("both output and error output must be provided"))
|
allErrs = append(allErrs, errors.New("both output and error output must be provided"))
|
||||||
}
|
}
|
||||||
if p.Attach == nil || p.PodClient == nil || p.Config == nil {
|
if p.Attach == nil || p.PodClient == nil || p.Config == nil {
|
||||||
@ -236,8 +235,8 @@ func (p *AttachOptions) Run() error {
|
|||||||
}
|
}
|
||||||
if p.TTY && !containerToAttach.TTY {
|
if p.TTY && !containerToAttach.TTY {
|
||||||
p.TTY = false
|
p.TTY = false
|
||||||
if p.Err != nil {
|
if p.ErrOut != nil {
|
||||||
fmt.Fprintf(p.Err, "Unable to use a TTY - container %s did not allocate one\n", containerToAttach.Name)
|
fmt.Fprintf(p.ErrOut, "Unable to use a TTY - container %s did not allocate one\n", containerToAttach.Name)
|
||||||
}
|
}
|
||||||
} else if !p.TTY && containerToAttach.TTY {
|
} else if !p.TTY && containerToAttach.TTY {
|
||||||
// the container was launched with a TTY, so we have to force a TTY here, otherwise you'll get
|
// the container was launched with a TTY, so we have to force a TTY here, otherwise you'll get
|
||||||
@ -249,7 +248,7 @@ func (p *AttachOptions) Run() error {
|
|||||||
t := p.setupTTY()
|
t := p.setupTTY()
|
||||||
|
|
||||||
// save p.Err so we can print the command prompt message below
|
// save p.Err so we can print the command prompt message below
|
||||||
stderr := p.Err
|
stderr := p.ErrOut
|
||||||
|
|
||||||
var sizeQueue remotecommand.TerminalSizeQueue
|
var sizeQueue remotecommand.TerminalSizeQueue
|
||||||
if t.Raw {
|
if t.Raw {
|
||||||
@ -266,7 +265,7 @@ func (p *AttachOptions) Run() error {
|
|||||||
|
|
||||||
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
||||||
// true
|
// true
|
||||||
p.Err = nil
|
p.ErrOut = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := func() error {
|
fn := func() error {
|
||||||
@ -284,11 +283,11 @@ func (p *AttachOptions) Run() error {
|
|||||||
Container: containerToAttach.Name,
|
Container: containerToAttach.Name,
|
||||||
Stdin: p.Stdin,
|
Stdin: p.Stdin,
|
||||||
Stdout: p.Out != nil,
|
Stdout: p.Out != nil,
|
||||||
Stderr: p.Err != nil,
|
Stderr: p.ErrOut != nil,
|
||||||
TTY: t.Raw,
|
TTY: t.Raw,
|
||||||
}, legacyscheme.ParameterCodec)
|
}, legacyscheme.ParameterCodec)
|
||||||
|
|
||||||
return p.Attach.Attach("POST", req.URL(), p.Config, p.In, p.Out, p.Err, t.Raw, sizeQueue)
|
return p.Attach.Attach("POST", req.URL(), p.Config, p.In, p.Out, p.ErrOut, t.Raw, sizeQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !p.Quiet && stderr != nil {
|
if !p.Quiet && stderr != nil {
|
||||||
@ -322,8 +321,8 @@ func (p *AttachOptions) containerToAttachTo(pod *api.Pod) (*api.Container, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(p.SuggestedCmdUsage) > 0 {
|
if len(p.SuggestedCmdUsage) > 0 {
|
||||||
fmt.Fprintf(p.Err, "Defaulting container name to %s.\n", pod.Spec.Containers[0].Name)
|
fmt.Fprintf(p.ErrOut, "Defaulting container name to %s.\n", pod.Spec.Containers[0].Name)
|
||||||
fmt.Fprintf(p.Err, "%s\n", p.SuggestedCmdUsage)
|
fmt.Fprintf(p.ErrOut, "%s\n", p.SuggestedCmdUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(4).Infof("defaulting container name to %s", pod.Spec.Containers[0].Name)
|
glog.V(4).Infof("defaulting container name to %s", pod.Spec.Containers[0].Name)
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -38,6 +37,7 @@ import (
|
|||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -249,9 +249,6 @@ func TestAttach(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
||||||
bufOut := bytes.NewBuffer([]byte{})
|
|
||||||
bufErr := bytes.NewBuffer([]byte{})
|
|
||||||
bufIn := bytes.NewBuffer([]byte{})
|
|
||||||
remoteAttach := &fakeRemoteAttach{}
|
remoteAttach := &fakeRemoteAttach{}
|
||||||
if test.remoteAttachErr {
|
if test.remoteAttachErr {
|
||||||
remoteAttach.err = fmt.Errorf("attach error")
|
remoteAttach.err = fmt.Errorf("attach error")
|
||||||
@ -259,9 +256,7 @@ func TestAttach(t *testing.T) {
|
|||||||
params := &AttachOptions{
|
params := &AttachOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
ContainerName: test.container,
|
ContainerName: test.container,
|
||||||
In: bufIn,
|
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||||
Out: bufOut,
|
|
||||||
Err: bufErr,
|
|
||||||
},
|
},
|
||||||
Attach: remoteAttach,
|
Attach: remoteAttach,
|
||||||
GetPodTimeout: 1000,
|
GetPodTimeout: 1000,
|
||||||
@ -342,16 +337,12 @@ func TestAttachWarnings(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
||||||
bufOut := bytes.NewBuffer([]byte{})
|
streams, _, _, bufErr := genericclioptions.NewTestIOStreams()
|
||||||
bufErr := bytes.NewBuffer([]byte{})
|
|
||||||
bufIn := bytes.NewBuffer([]byte{})
|
|
||||||
ex := &fakeRemoteAttach{}
|
ex := &fakeRemoteAttach{}
|
||||||
params := &AttachOptions{
|
params := &AttachOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
ContainerName: test.container,
|
ContainerName: test.container,
|
||||||
In: bufIn,
|
IOStreams: streams,
|
||||||
Out: bufOut,
|
|
||||||
Err: bufErr,
|
|
||||||
Stdin: test.stdin,
|
Stdin: test.stdin,
|
||||||
TTY: test.tty,
|
TTY: test.tty,
|
||||||
},
|
},
|
||||||
|
@ -275,7 +275,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
NewCmdExplain("kubectl", f, ioStreams),
|
NewCmdExplain("kubectl", f, ioStreams),
|
||||||
get.NewCmdGet("kubectl", f, ioStreams),
|
get.NewCmdGet("kubectl", f, ioStreams),
|
||||||
NewCmdEdit(f, ioStreams),
|
NewCmdEdit(f, ioStreams),
|
||||||
NewCmdDelete(f, out, err),
|
NewCmdDelete(f, ioStreams),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -292,7 +292,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
NewCmdCertificate(f, ioStreams),
|
NewCmdCertificate(f, ioStreams),
|
||||||
NewCmdClusterInfo(f, ioStreams),
|
NewCmdClusterInfo(f, ioStreams),
|
||||||
NewCmdTop(f, out, err),
|
NewCmdTop(f, ioStreams),
|
||||||
NewCmdCordon(f, ioStreams),
|
NewCmdCordon(f, ioStreams),
|
||||||
NewCmdUncordon(f, ioStreams),
|
NewCmdUncordon(f, ioStreams),
|
||||||
NewCmdDrain(f, ioStreams),
|
NewCmdDrain(f, ioStreams),
|
||||||
@ -303,11 +303,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
Message: "Troubleshooting and Debugging Commands:",
|
Message: "Troubleshooting and Debugging Commands:",
|
||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
NewCmdDescribe("kubectl", f, ioStreams),
|
NewCmdDescribe("kubectl", f, ioStreams),
|
||||||
NewCmdLogs(f, out, err),
|
NewCmdLogs(f, ioStreams),
|
||||||
NewCmdAttach(f, in, out, err),
|
NewCmdAttach(f, ioStreams),
|
||||||
NewCmdExec(f, in, out, err),
|
NewCmdExec(f, ioStreams),
|
||||||
NewCmdPortForward(f, out, err),
|
NewCmdPortForward(f, ioStreams),
|
||||||
NewCmdProxy(f, out),
|
NewCmdProxy(f, ioStreams),
|
||||||
NewCmdCp(f, ioStreams),
|
NewCmdCp(f, ioStreams),
|
||||||
auth.NewCmdAuth(f, ioStreams),
|
auth.NewCmdAuth(f, ioStreams),
|
||||||
},
|
},
|
||||||
@ -317,7 +317,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
NewCmdApply("kubectl", f, ioStreams),
|
NewCmdApply("kubectl", f, ioStreams),
|
||||||
NewCmdPatch(f, ioStreams),
|
NewCmdPatch(f, ioStreams),
|
||||||
NewCmdReplace(f, out, err),
|
NewCmdReplace(f, ioStreams),
|
||||||
NewCmdConvert(f, ioStreams),
|
NewCmdConvert(f, ioStreams),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -326,7 +326,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
Commands: []*cobra.Command{
|
Commands: []*cobra.Command{
|
||||||
NewCmdLabel(f, ioStreams),
|
NewCmdLabel(f, ioStreams),
|
||||||
NewCmdAnnotate("kubectl", f, ioStreams),
|
NewCmdAnnotate("kubectl", f, ioStreams),
|
||||||
NewCmdCompletion(out, ""),
|
NewCmdCompletion(ioStreams.Out, ""),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -335,7 +335,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
filters := []string{"options"}
|
filters := []string{"options"}
|
||||||
|
|
||||||
// Hide the "alpha" subcommand if there are no alpha commands in this build.
|
// Hide the "alpha" subcommand if there are no alpha commands in this build.
|
||||||
alpha := NewCmdAlpha(f, in, out, err)
|
alpha := NewCmdAlpha(f, ioStreams)
|
||||||
if !alpha.HasSubCommands() {
|
if !alpha.HasSubCommands() {
|
||||||
filters = append(filters, alpha.Name())
|
filters = append(filters, alpha.Name())
|
||||||
}
|
}
|
||||||
@ -356,11 +356,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
|
|
||||||
cmds.AddCommand(alpha)
|
cmds.AddCommand(alpha)
|
||||||
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
|
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
|
||||||
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
cmds.AddCommand(NewCmdPlugin(f, ioStreams))
|
||||||
cmds.AddCommand(NewCmdVersion(f, ioStreams))
|
cmds.AddCommand(NewCmdVersion(f, ioStreams))
|
||||||
cmds.AddCommand(NewCmdApiVersions(f, ioStreams))
|
cmds.AddCommand(NewCmdApiVersions(f, ioStreams))
|
||||||
cmds.AddCommand(NewCmdApiResources(f, ioStreams))
|
cmds.AddCommand(NewCmdApiResources(f, ioStreams))
|
||||||
cmds.AddCommand(NewCmdOptions(out))
|
cmds.AddCommand(NewCmdOptions(ioStreams.Out))
|
||||||
|
|
||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -35,6 +34,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
|
|
||||||
|
"bytes"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
"github.com/renstrom/dedent"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -194,8 +195,10 @@ func (o *CopyOptions) Run(args []string) error {
|
|||||||
func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
|
func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
|
||||||
options := &ExecOptions{
|
options := &ExecOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
Out: bytes.NewBuffer([]byte{}),
|
IOStreams: genericclioptions.IOStreams{
|
||||||
Err: bytes.NewBuffer([]byte{}),
|
Out: bytes.NewBuffer([]byte{}),
|
||||||
|
ErrOut: bytes.NewBuffer([]byte{}),
|
||||||
|
},
|
||||||
|
|
||||||
Namespace: dest.PodNamespace,
|
Namespace: dest.PodNamespace,
|
||||||
PodName: dest.PodName,
|
PodName: dest.PodName,
|
||||||
@ -240,9 +243,11 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error {
|
|||||||
|
|
||||||
options := &ExecOptions{
|
options := &ExecOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
In: reader,
|
IOStreams: genericclioptions.IOStreams{
|
||||||
Out: o.Out,
|
In: reader,
|
||||||
Err: o.ErrOut,
|
Out: o.Out,
|
||||||
|
ErrOut: o.ErrOut,
|
||||||
|
},
|
||||||
Stdin: true,
|
Stdin: true,
|
||||||
|
|
||||||
Namespace: dest.PodNamespace,
|
Namespace: dest.PodNamespace,
|
||||||
@ -263,9 +268,11 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
|
|||||||
reader, outStream := io.Pipe()
|
reader, outStream := io.Pipe()
|
||||||
options := &ExecOptions{
|
options := &ExecOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
In: nil,
|
IOStreams: genericclioptions.IOStreams{
|
||||||
Out: outStream,
|
In: nil,
|
||||||
Err: o.Out,
|
Out: outStream,
|
||||||
|
ErrOut: o.Out,
|
||||||
|
},
|
||||||
|
|
||||||
Namespace: src.PodNamespace,
|
Namespace: src.PodNamespace,
|
||||||
PodName: src.PodName,
|
PodName: src.PodName,
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -31,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -109,11 +109,10 @@ type DeleteOptions struct {
|
|||||||
Mapper meta.RESTMapper
|
Mapper meta.RESTMapper
|
||||||
Result *resource.Result
|
Result *resource.Result
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
ErrOut io.Writer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")
|
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -123,14 +122,14 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Long: delete_long,
|
Long: delete_long,
|
||||||
Example: delete_example,
|
Example: delete_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
options := deleteFlags.ToOptions(out, errOut)
|
o := deleteFlags.ToOptions(streams)
|
||||||
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
if err := o.Complete(f, args, cmd); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(cmd); err != nil {
|
if err := o.Validate(cmd); err != nil {
|
||||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, err.Error()))
|
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, err.Error()))
|
||||||
}
|
}
|
||||||
if err := options.RunDelete(); err != nil {
|
if err := o.RunDelete(); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -143,7 +142,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string, cmd *cobra.Command) error {
|
func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Command) error {
|
||||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -195,10 +194,6 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up writer
|
|
||||||
o.Out = out
|
|
||||||
o.ErrOut = errOut
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -72,10 +72,9 @@ type DeleteFlags struct {
|
|||||||
Output *string
|
Output *string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *DeleteFlags) ToOptions(out, errOut io.Writer) *DeleteOptions {
|
func (f *DeleteFlags) ToOptions(streams genericclioptions.IOStreams) *DeleteOptions {
|
||||||
options := &DeleteOptions{
|
options := &DeleteOptions{
|
||||||
Out: out,
|
IOStreams: streams,
|
||||||
ErrOut: errOut,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add filename options
|
// add filename options
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -38,6 +37,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
@ -84,8 +84,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
|
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -95,8 +95,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
||||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
cmd = NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
cmd.Run(cmd, []string{"secrets/mysecret"})
|
cmd.Run(cmd, []string{"secrets/mysecret"})
|
||||||
@ -147,8 +147,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
|
|||||||
// DeleteOptions.OrphanDependents should be false, when cascade is true (default).
|
// DeleteOptions.OrphanDependents should be false, when cascade is true (default).
|
||||||
falseVar := false
|
falseVar := false
|
||||||
expectedOrphanDependents = &falseVar
|
expectedOrphanDependents = &falseVar
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
cmd.Run(cmd, []string{"secrets/mysecret"})
|
cmd.Run(cmd, []string{"secrets/mysecret"})
|
||||||
@ -159,8 +159,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
|
|||||||
// Test that delete options should be set to orphan when cascade is false.
|
// Test that delete options should be set to orphan when cascade is false.
|
||||||
trueVar := true
|
trueVar := true
|
||||||
expectedOrphanDependents = &trueVar
|
expectedOrphanDependents = &trueVar
|
||||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
cmd = NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -202,8 +202,8 @@ func TestDeleteNamedObject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
|
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -213,8 +213,8 @@ func TestDeleteNamedObject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
||||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
cmd = NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -246,9 +246,9 @@ func TestDeleteObject(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -318,11 +318,11 @@ func TestDeleteObjectGraceZero(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
reaper := &fakeReaper{}
|
reaper := &fakeReaper{}
|
||||||
fake := &fakeReaperFactory{Factory: tf, reaper: reaper}
|
fake := &fakeReaperFactory{Factory: tf, reaper: reaper}
|
||||||
cmd := NewCmdDelete(fake, buf, errBuf)
|
streams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||||
|
cmd := NewCmdDelete(fake, streams)
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
cmd.Flags().Set("grace-period", "0")
|
cmd.Flags().Set("grace-period", "0")
|
||||||
cmd.Run(cmd, []string{"pods/nginx"})
|
cmd.Run(cmd, []string{"pods/nginx"})
|
||||||
@ -357,7 +357,6 @@ func TestDeleteObjectNotFound(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
options := &DeleteOptions{
|
options := &DeleteOptions{
|
||||||
FilenameOptions: resource.FilenameOptions{
|
FilenameOptions: resource.FilenameOptions{
|
||||||
@ -366,8 +365,9 @@ func TestDeleteObjectNotFound(t *testing.T) {
|
|||||||
GracePeriod: -1,
|
GracePeriod: -1,
|
||||||
Cascade: false,
|
Cascade: false,
|
||||||
Output: "name",
|
Output: "name",
|
||||||
|
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||||
}
|
}
|
||||||
err := options.Complete(tf, buf, errBuf, []string{}, fakecmd())
|
err := options.Complete(tf, []string{}, fakecmd())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -395,9 +395,9 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("ignore-not-found", "true")
|
cmd.Flags().Set("ignore-not-found", "true")
|
||||||
@ -438,7 +438,6 @@ func TestDeleteAllNotFound(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
// Make sure we can explicitly choose to fail on NotFound errors, even with --all
|
// Make sure we can explicitly choose to fail on NotFound errors, even with --all
|
||||||
options := &DeleteOptions{
|
options := &DeleteOptions{
|
||||||
@ -448,8 +447,9 @@ func TestDeleteAllNotFound(t *testing.T) {
|
|||||||
DeleteAll: true,
|
DeleteAll: true,
|
||||||
IgnoreNotFound: false,
|
IgnoreNotFound: false,
|
||||||
Output: "name",
|
Output: "name",
|
||||||
|
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||||
}
|
}
|
||||||
err := options.Complete(tf, buf, errBuf, []string{"services"}, fakecmd())
|
err := options.Complete(tf, []string{"services"}, fakecmd())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -489,9 +489,9 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("all", "true")
|
cmd.Flags().Set("all", "true")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -526,9 +526,9 @@ func TestDeleteMultipleObject(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
@ -564,7 +564,7 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
options := &DeleteOptions{
|
options := &DeleteOptions{
|
||||||
FilenameOptions: resource.FilenameOptions{
|
FilenameOptions: resource.FilenameOptions{
|
||||||
@ -573,8 +573,9 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
|
|||||||
GracePeriod: -1,
|
GracePeriod: -1,
|
||||||
Cascade: false,
|
Cascade: false,
|
||||||
Output: "name",
|
Output: "name",
|
||||||
|
IOStreams: streams,
|
||||||
}
|
}
|
||||||
err := options.Complete(tf, buf, errBuf, []string{}, fakecmd())
|
err := options.Complete(tf, []string{}, fakecmd())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
@ -616,9 +617,9 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -650,9 +651,9 @@ func TestDeleteDirectory(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -697,9 +698,9 @@ func TestDeleteMultipleSelector(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
cmd := NewCmdDelete(tf, streams)
|
||||||
cmd.Flags().Set("selector", "a=b")
|
cmd.Flags().Set("selector", "a=b")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -742,15 +743,15 @@ func TestResourceErrors(t *testing.T) {
|
|||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
|
|
||||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
options := &DeleteOptions{
|
options := &DeleteOptions{
|
||||||
FilenameOptions: resource.FilenameOptions{},
|
FilenameOptions: resource.FilenameOptions{},
|
||||||
GracePeriod: -1,
|
GracePeriod: -1,
|
||||||
Cascade: false,
|
Cascade: false,
|
||||||
Output: "name",
|
Output: "name",
|
||||||
|
IOStreams: streams,
|
||||||
}
|
}
|
||||||
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd())
|
err := options.Complete(tf, testCase.args, fakecmd())
|
||||||
if !testCase.errFn(err) {
|
if !testCase.errFn(err) {
|
||||||
t.Errorf("%s: unexpected error: %v", k, err)
|
t.Errorf("%s: unexpected error: %v", k, err)
|
||||||
return
|
return
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubectl/apply/strategy"
|
"k8s.io/kubernetes/pkg/kubectl/apply/strategy"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/utils/exec"
|
"k8s.io/utils/exec"
|
||||||
@ -101,12 +102,11 @@ func parseDiffArguments(args []string) (string, string, error) {
|
|||||||
return from, to, nil
|
return from, to, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdDiff(f cmdutil.Factory, stdout, stderr io.Writer) *cobra.Command {
|
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
var options DiffOptions
|
var options DiffOptions
|
||||||
diff := DiffProgram{
|
diff := DiffProgram{
|
||||||
Exec: exec.New(),
|
Exec: exec.New(),
|
||||||
Stdout: stdout,
|
IOStreams: streams,
|
||||||
Stderr: stderr,
|
|
||||||
}
|
}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "diff -f FILENAME",
|
Use: "diff -f FILENAME",
|
||||||
@ -132,9 +132,8 @@ func NewCmdDiff(f cmdutil.Factory, stdout, stderr io.Writer) *cobra.Command {
|
|||||||
// KUBERNETES_EXTERNAL_DIFF environment variable will be used a diff
|
// KUBERNETES_EXTERNAL_DIFF environment variable will be used a diff
|
||||||
// program. By default, `diff(1)` will be used.
|
// program. By default, `diff(1)` will be used.
|
||||||
type DiffProgram struct {
|
type DiffProgram struct {
|
||||||
Exec exec.Interface
|
Exec exec.Interface
|
||||||
Stdout io.Writer
|
genericclioptions.IOStreams
|
||||||
Stderr io.Writer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
||||||
@ -147,8 +146,8 @@ func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd := d.Exec.Command(diff, args...)
|
cmd := d.Exec.Command(diff, args...)
|
||||||
cmd.SetStdout(d.Stdout)
|
cmd.SetStdout(d.Out)
|
||||||
cmd.SetStderr(d.Stderr)
|
cmd.SetStderr(d.ErrOut)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/utils/exec"
|
"k8s.io/utils/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -137,11 +138,10 @@ func TestArguments(t *testing.T) {
|
|||||||
|
|
||||||
func TestDiffProgram(t *testing.T) {
|
func TestDiffProgram(t *testing.T) {
|
||||||
os.Setenv("KUBERNETES_EXTERNAL_DIFF", "echo")
|
os.Setenv("KUBERNETES_EXTERNAL_DIFF", "echo")
|
||||||
stdout := bytes.Buffer{}
|
streams, _, stdout, _ := genericclioptions.NewTestIOStreams()
|
||||||
diff := DiffProgram{
|
diff := DiffProgram{
|
||||||
Stdout: &stdout,
|
IOStreams: streams,
|
||||||
Stderr: &bytes.Buffer{},
|
Exec: exec.New(),
|
||||||
Exec: exec.New(),
|
|
||||||
}
|
}
|
||||||
err := diff.Run("one", "two")
|
err := diff.Run("one", "two")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
||||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||||
@ -62,12 +63,10 @@ const (
|
|||||||
execUsageStr = "expected 'exec POD_NAME COMMAND [ARG1] [ARG2] ... [ARGN]'.\nPOD_NAME and COMMAND are required arguments for the exec command"
|
execUsageStr = "expected 'exec POD_NAME COMMAND [ARG1] [ARG2] ... [ARGN]'.\nPOD_NAME and COMMAND are required arguments for the exec command"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdExec(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
|
func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
options := &ExecOptions{
|
options := &ExecOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
In: cmdIn,
|
IOStreams: streams,
|
||||||
Out: cmdOut,
|
|
||||||
Err: cmdErr,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Executor: &DefaultRemoteExecutor{},
|
Executor: &DefaultRemoteExecutor{},
|
||||||
@ -125,9 +124,8 @@ type StreamOptions struct {
|
|||||||
Quiet bool
|
Quiet bool
|
||||||
// InterruptParent, if set, is used to handle interrupts while attached
|
// InterruptParent, if set, is used to handle interrupts while attached
|
||||||
InterruptParent *interrupt.Handler
|
InterruptParent *interrupt.Handler
|
||||||
In io.Reader
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
Err io.Writer
|
|
||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
overrideStreams func() (io.ReadCloser, io.Writer, io.Writer)
|
overrideStreams func() (io.ReadCloser, io.Writer, io.Writer)
|
||||||
@ -155,7 +153,7 @@ func (p *ExecOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn []s
|
|||||||
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
||||||
}
|
}
|
||||||
if len(p.PodName) != 0 {
|
if len(p.PodName) != 0 {
|
||||||
printDeprecationWarning(p.Err, "exec POD_NAME", "-p POD_NAME")
|
printDeprecationWarning(p.ErrOut, "exec POD_NAME", "-p POD_NAME")
|
||||||
if len(argsIn) < 1 {
|
if len(argsIn) < 1 {
|
||||||
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
||||||
}
|
}
|
||||||
@ -205,7 +203,7 @@ func (p *ExecOptions) Validate() error {
|
|||||||
if len(p.Command) == 0 {
|
if len(p.Command) == 0 {
|
||||||
return fmt.Errorf("you must specify at least one command for the container")
|
return fmt.Errorf("you must specify at least one command for the container")
|
||||||
}
|
}
|
||||||
if p.Out == nil || p.Err == nil {
|
if p.Out == nil || p.ErrOut == nil {
|
||||||
return fmt.Errorf("both output and error output must be provided")
|
return fmt.Errorf("both output and error output must be provided")
|
||||||
}
|
}
|
||||||
if p.Executor == nil || p.PodClient == nil || p.Config == nil {
|
if p.Executor == nil || p.PodClient == nil || p.Config == nil {
|
||||||
@ -240,8 +238,8 @@ func (o *StreamOptions) setupTTY() term.TTY {
|
|||||||
if !o.isTerminalIn(t) {
|
if !o.isTerminalIn(t) {
|
||||||
o.TTY = false
|
o.TTY = false
|
||||||
|
|
||||||
if o.Err != nil {
|
if o.ErrOut != nil {
|
||||||
fmt.Fprintln(o.Err, "Unable to use a TTY - input is not a terminal or the right kind of file")
|
fmt.Fprintln(o.ErrOut, "Unable to use a TTY - input is not a terminal or the right kind of file")
|
||||||
}
|
}
|
||||||
|
|
||||||
return t
|
return t
|
||||||
@ -284,7 +282,7 @@ func (p *ExecOptions) Run() error {
|
|||||||
if len(p.SuggestedCmdUsage) > 0 {
|
if len(p.SuggestedCmdUsage) > 0 {
|
||||||
usageString = fmt.Sprintf("%s\n%s", usageString, p.SuggestedCmdUsage)
|
usageString = fmt.Sprintf("%s\n%s", usageString, p.SuggestedCmdUsage)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(p.Err, "%s\n", usageString)
|
fmt.Fprintf(p.ErrOut, "%s\n", usageString)
|
||||||
}
|
}
|
||||||
containerName = pod.Spec.Containers[0].Name
|
containerName = pod.Spec.Containers[0].Name
|
||||||
}
|
}
|
||||||
@ -299,7 +297,7 @@ func (p *ExecOptions) Run() error {
|
|||||||
|
|
||||||
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
||||||
// true
|
// true
|
||||||
p.Err = nil
|
p.ErrOut = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fn := func() error {
|
fn := func() error {
|
||||||
@ -320,11 +318,11 @@ func (p *ExecOptions) Run() error {
|
|||||||
Command: p.Command,
|
Command: p.Command,
|
||||||
Stdin: p.Stdin,
|
Stdin: p.Stdin,
|
||||||
Stdout: p.Out != nil,
|
Stdout: p.Out != nil,
|
||||||
Stderr: p.Err != nil,
|
Stderr: p.ErrOut != nil,
|
||||||
TTY: t.Raw,
|
TTY: t.Raw,
|
||||||
}, legacyscheme.ParameterCodec)
|
}, legacyscheme.ParameterCodec)
|
||||||
|
|
||||||
return p.Executor.Execute("POST", req.URL(), p.Config, p.In, p.Out, p.Err, t.Raw, sizeQueue)
|
return p.Executor.Execute("POST", req.URL(), p.Config, p.In, p.Out, p.ErrOut, t.Raw, sizeQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.Safe(fn); err != nil {
|
if err := t.Safe(fn); err != nil {
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
||||||
)
|
)
|
||||||
@ -145,7 +146,7 @@ func TestPodAndContainer(t *testing.T) {
|
|||||||
|
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
options := test.p
|
options := test.p
|
||||||
options.Err = bytes.NewBuffer([]byte{})
|
options.ErrOut = bytes.NewBuffer([]byte{})
|
||||||
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
|
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
|
||||||
if test.expectError && err == nil {
|
if test.expectError && err == nil {
|
||||||
t.Errorf("%s: unexpected non-error", test.name)
|
t.Errorf("%s: unexpected non-error", test.name)
|
||||||
@ -213,9 +214,6 @@ func TestExec(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
bufOut := bytes.NewBuffer([]byte{})
|
|
||||||
bufErr := bytes.NewBuffer([]byte{})
|
|
||||||
bufIn := bytes.NewBuffer([]byte{})
|
|
||||||
ex := &fakeRemoteExecutor{}
|
ex := &fakeRemoteExecutor{}
|
||||||
if test.execErr {
|
if test.execErr {
|
||||||
ex.execErr = fmt.Errorf("exec error")
|
ex.execErr = fmt.Errorf("exec error")
|
||||||
@ -224,9 +222,7 @@ func TestExec(t *testing.T) {
|
|||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
PodName: "foo",
|
PodName: "foo",
|
||||||
ContainerName: "bar",
|
ContainerName: "bar",
|
||||||
In: bufIn,
|
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||||
Out: bufOut,
|
|
||||||
Err: bufErr,
|
|
||||||
},
|
},
|
||||||
Executor: ex,
|
Executor: ex,
|
||||||
}
|
}
|
||||||
@ -277,16 +273,14 @@ func execPod() *api.Pod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSetupTTY(t *testing.T) {
|
func TestSetupTTY(t *testing.T) {
|
||||||
stderr := &bytes.Buffer{}
|
streams, _, _, stderr := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
// test 1 - don't attach stdin
|
// test 1 - don't attach stdin
|
||||||
o := &StreamOptions{
|
o := &StreamOptions{
|
||||||
// InterruptParent: ,
|
// InterruptParent: ,
|
||||||
Stdin: false,
|
Stdin: false,
|
||||||
In: &bytes.Buffer{},
|
IOStreams: streams,
|
||||||
Out: &bytes.Buffer{},
|
TTY: true,
|
||||||
Err: stderr,
|
|
||||||
TTY: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tty := o.setupTTY()
|
tty := o.setupTTY()
|
||||||
@ -334,7 +328,7 @@ func TestSetupTTY(t *testing.T) {
|
|||||||
// test 3 - request a TTY, but stdin is not a terminal
|
// test 3 - request a TTY, but stdin is not a terminal
|
||||||
o.Stdin = true
|
o.Stdin = true
|
||||||
o.In = &bytes.Buffer{}
|
o.In = &bytes.Buffer{}
|
||||||
o.Err = stderr
|
o.ErrOut = stderr
|
||||||
o.TTY = true
|
o.TTY = true
|
||||||
|
|
||||||
tty = o.setupTTY()
|
tty = o.setupTTY()
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util"
|
"k8s.io/kubernetes/pkg/kubectl/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -89,12 +90,19 @@ type LogsOptions struct {
|
|||||||
GetPodTimeout time.Duration
|
GetPodTimeout time.Duration
|
||||||
LogsForObject func(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error)
|
LogsForObject func(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error)
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLogsOptions(streams genericclioptions.IOStreams) *LogsOptions {
|
||||||
|
return &LogsOptions{
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdLogs creates a new pod logs command
|
// NewCmdLogs creates a new pod logs command
|
||||||
func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := &LogsOptions{}
|
o := NewLogsOptions(streams)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]",
|
Use: "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
@ -103,11 +111,11 @@ func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Example: logsExample,
|
Example: logsExample,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
if len(os.Args) > 1 && os.Args[1] == "log" {
|
if len(os.Args) > 1 && os.Args[1] == "log" {
|
||||||
printDeprecationWarning(errOut, "logs", "log")
|
printDeprecationWarning(o.ErrOut, "logs", "log")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(f, out, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
cmdutil.CheckErr(o.RunLogs())
|
cmdutil.CheckErr(o.RunLogs())
|
||||||
},
|
},
|
||||||
@ -129,7 +137,7 @@ func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
containerName := cmdutil.GetFlagString(cmd, "container")
|
containerName := cmdutil.GetFlagString(cmd, "container")
|
||||||
selector := cmdutil.GetFlagString(cmd, "selector")
|
selector := cmdutil.GetFlagString(cmd, "selector")
|
||||||
o.AllContainers = cmdutil.GetFlagBool(cmd, "all-containers")
|
o.AllContainers = cmdutil.GetFlagBool(cmd, "all-containers")
|
||||||
@ -189,7 +197,6 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm
|
|||||||
}
|
}
|
||||||
o.Options = logOptions
|
o.Options = logOptions
|
||||||
o.LogsForObject = f.LogsForObject
|
o.LogsForObject = f.LogsForObject
|
||||||
o.Out = out
|
|
||||||
|
|
||||||
if len(selector) != 0 {
|
if len(selector) != 0 {
|
||||||
if logOptions.Follow {
|
if logOptions.Follow {
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -31,6 +30,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -74,9 +74,9 @@ func TestLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdLogs(tf, buf, buf)
|
cmd := NewCmdLogs(tf, streams)
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Run(cmd, []string{"foo"})
|
cmd.Run(cmd, []string{"foo"})
|
||||||
|
|
||||||
@ -144,17 +144,17 @@ func TestValidateLogFlags(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams := genericclioptions.NewTestIOStreamsDiscard()
|
||||||
cmd := NewCmdLogs(f, buf, buf)
|
cmd := NewCmdLogs(f, streams)
|
||||||
out := ""
|
out := ""
|
||||||
for flag, value := range test.flags {
|
for flag, value := range test.flags {
|
||||||
cmd.Flags().Set(flag, value)
|
cmd.Flags().Set(flag, value)
|
||||||
}
|
}
|
||||||
// checkErr breaks tests in case of errors, plus we just
|
// checkErr breaks tests in case of errors, plus we just
|
||||||
// need to check errors returned by the command validation
|
// need to check errors returned by the command validation
|
||||||
o := &LogsOptions{}
|
o := NewLogsOptions(streams)
|
||||||
cmd.Run = func(cmd *cobra.Command, args []string) {
|
cmd.Run = func(cmd *cobra.Command, args []string) {
|
||||||
o.Complete(f, os.Stdout, cmd, args)
|
o.Complete(f, cmd, args)
|
||||||
out = o.Validate().Error()
|
out = o.Validate().Error()
|
||||||
}
|
}
|
||||||
cmd.Run(cmd, test.args)
|
cmd.Run(cmd, test.args)
|
||||||
@ -205,8 +205,7 @@ func TestLogComplete(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
buf := bytes.NewBuffer([]byte{})
|
cmd := NewCmdLogs(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||||
cmd := NewCmdLogs(f, buf, buf)
|
|
||||||
var err error
|
var err error
|
||||||
out := ""
|
out := ""
|
||||||
for flag, value := range test.flags {
|
for flag, value := range test.flags {
|
||||||
@ -214,8 +213,8 @@ func TestLogComplete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// checkErr breaks tests in case of errors, plus we just
|
// checkErr breaks tests in case of errors, plus we just
|
||||||
// need to check errors returned by the command validation
|
// need to check errors returned by the command validation
|
||||||
o := &LogsOptions{}
|
o := NewLogsOptions(genericclioptions.NewTestIOStreamsDiscard())
|
||||||
err = o.Complete(f, os.Stdout, cmd, test.args)
|
err = o.Complete(f, cmd, test.args)
|
||||||
out = err.Error()
|
out = err.Error()
|
||||||
if !strings.Contains(out, test.expected) {
|
if !strings.Contains(out, test.expected) {
|
||||||
t.Errorf("%s: expected to find:\n\t%s\nfound:\n\t%s\n", test.name, test.expected, out)
|
t.Errorf("%s: expected to find:\n\t%s\nfound:\n\t%s\n", test.name, test.expected, out)
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -28,6 +27,7 @@ import (
|
|||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -42,7 +42,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdPlugin creates the command that is the top-level for plugin commands.
|
// NewCmdPlugin creates the command that is the top-level for plugin commands.
|
||||||
func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
|
func NewCmdPlugin(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
// Loads plugins and create commands for each plugin identified
|
// Loads plugins and create commands for each plugin identified
|
||||||
loadedPlugins, loadErr := f.PluginLoader().Load()
|
loadedPlugins, loadErr := f.PluginLoader().Load()
|
||||||
if loadErr != nil {
|
if loadErr != nil {
|
||||||
@ -58,14 +58,14 @@ func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Co
|
|||||||
if len(loadedPlugins) == 0 {
|
if len(loadedPlugins) == 0 {
|
||||||
cmdutil.CheckErr(fmt.Errorf("no plugins installed."))
|
cmdutil.CheckErr(fmt.Errorf("no plugins installed."))
|
||||||
}
|
}
|
||||||
cmdutil.DefaultSubCommandRun(err)(cmd, args)
|
cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(loadedPlugins) > 0 {
|
if len(loadedPlugins) > 0 {
|
||||||
pluginRunner := f.PluginRunner()
|
pluginRunner := f.PluginRunner()
|
||||||
for _, p := range loadedPlugins {
|
for _, p := range loadedPlugins {
|
||||||
cmd.AddCommand(NewCmdForPlugin(f, p, pluginRunner, in, out, err))
|
cmd.AddCommand(NewCmdForPlugin(f, p, pluginRunner, streams))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdForPlugin creates a command capable of running the provided plugin.
|
// NewCmdForPlugin creates a command capable of running the provided plugin.
|
||||||
func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.PluginRunner, in io.Reader, out, errout io.Writer) *cobra.Command {
|
func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.PluginRunner, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
if !plugin.IsValid() {
|
if !plugin.IsValid() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||||||
Example: templates.Examples(plugin.Example),
|
Example: templates.Examples(plugin.Example),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if len(plugin.Command) == 0 {
|
if len(plugin.Command) == 0 {
|
||||||
cmdutil.DefaultSubCommandRun(errout)(cmd, args)
|
cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +104,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
runningContext := plugins.RunningContext{
|
runningContext := plugins.RunningContext{
|
||||||
In: in,
|
IOStreams: streams,
|
||||||
Out: out,
|
|
||||||
ErrOut: errout,
|
|
||||||
Args: args,
|
Args: args,
|
||||||
EnvProvider: envProvider,
|
EnvProvider: envProvider,
|
||||||
WorkingDir: plugin.Dir,
|
WorkingDir: plugin.Dir,
|
||||||
@ -117,7 +115,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||||||
// check for (and exit with) the correct exit code
|
// check for (and exit with) the correct exit code
|
||||||
// from a failed plugin command execution
|
// from a failed plugin command execution
|
||||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
fmt.Fprintf(errout, "error: %v\n", err)
|
fmt.Fprintf(streams.ErrOut, "error: %v\n", err)
|
||||||
os.Exit(status.ExitStatus())
|
os.Exit(status.ExitStatus())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,7 +130,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, childPlugin := range plugin.Tree {
|
for _, childPlugin := range plugin.Tree {
|
||||||
cmd.AddCommand(NewCmdForPlugin(f, childPlugin, runner, in, out, errout))
|
cmd.AddCommand(NewCmdForPlugin(f, childPlugin, runner, streams))
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,9 +81,7 @@ func TestPluginCmd(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
inBuf := bytes.NewBuffer([]byte{})
|
streams, _, outBuf, errBuf := genericclioptions.NewTestIOStreams()
|
||||||
outBuf := bytes.NewBuffer([]byte{})
|
|
||||||
errBuf := bytes.NewBuffer([]byte{})
|
|
||||||
|
|
||||||
cmdutil.BehaviorOnFatal(func(str string, code int) {
|
cmdutil.BehaviorOnFatal(func(str string, code int) {
|
||||||
errBuf.Write([]byte(str))
|
errBuf.Write([]byte(str))
|
||||||
@ -96,7 +94,7 @@ func TestPluginCmd(t *testing.T) {
|
|||||||
f := cmdtesting.NewTestFactory()
|
f := cmdtesting.NewTestFactory()
|
||||||
defer f.Cleanup()
|
defer f.Cleanup()
|
||||||
|
|
||||||
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
|
cmd := NewCmdForPlugin(f, test.plugin, runner, streams)
|
||||||
if cmd == nil {
|
if cmd == nil {
|
||||||
if !test.expectedNilCmd {
|
if !test.expectedNilCmd {
|
||||||
t.Fatalf("%s: command was unexpectedly not registered", test.name)
|
t.Fatalf("%s: command was unexpectedly not registered", test.name)
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -38,6 +37,7 @@ import (
|
|||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util"
|
"k8s.io/kubernetes/pkg/kubectl/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -84,11 +84,10 @@ const (
|
|||||||
defaultPodPortForwardWaitTimeout = 60 * time.Second
|
defaultPodPortForwardWaitTimeout = 60 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdPortForward(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
|
func NewCmdPortForward(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
opts := &PortForwardOptions{
|
opts := &PortForwardOptions{
|
||||||
PortForwarder: &defaultPortForwarder{
|
PortForwarder: &defaultPortForwarder{
|
||||||
cmdOut: cmdOut,
|
IOStreams: streams,
|
||||||
cmdErr: cmdErr,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -119,7 +118,7 @@ type portForwarder interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type defaultPortForwarder struct {
|
type defaultPortForwarder struct {
|
||||||
cmdOut, cmdErr io.Writer
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
|
func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
|
||||||
@ -128,7 +127,7 @@ func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts Po
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
|
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
|
||||||
fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.cmdOut, f.cmdErr)
|
fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.Out, f.ErrOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -32,6 +31,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
opts := &PortForwardOptions{}
|
opts := &PortForwardOptions{}
|
||||||
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
|
cmd := NewCmdPortForward(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||||
cmd.Run = func(cmd *cobra.Command, args []string) {
|
cmd.Run = func(cmd *cobra.Command, args []string) {
|
||||||
if err = opts.Complete(tf, cmd, args); err != nil {
|
if err = opts.Complete(tf, cmd, args); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/proxy"
|
"k8s.io/kubernetes/pkg/kubectl/proxy"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
@ -69,7 +70,7 @@ var (
|
|||||||
kubectl proxy --api-prefix=/k8s-api`))
|
kubectl proxy --api-prefix=/k8s-api`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
func NewCmdProxy(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
|
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
@ -77,7 +78,7 @@ func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
Long: proxyLong,
|
Long: proxyLong,
|
||||||
Example: proxyExample,
|
Example: proxyExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
err := RunProxy(f, out, cmd)
|
err := RunProxy(f, streams.Out, cmd)
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -86,11 +85,10 @@ type ReplaceOptions struct {
|
|||||||
|
|
||||||
Recorder genericclioptions.Recorder
|
Recorder genericclioptions.Recorder
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
ErrOut io.Writer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions {
|
||||||
outputFormat := ""
|
outputFormat := ""
|
||||||
|
|
||||||
return &ReplaceOptions{
|
return &ReplaceOptions{
|
||||||
@ -102,13 +100,12 @@ func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
|||||||
},
|
},
|
||||||
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
|
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
|
||||||
|
|
||||||
Out: out,
|
IOStreams: streams,
|
||||||
ErrOut: errOut,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCmdReplace(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := NewReplaceOptions(out, errOut)
|
o := NewReplaceOptions(streams)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "replace -f FILENAME",
|
Use: "replace -f FILENAME",
|
||||||
@ -154,7 +151,7 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||||||
return printer.PrintObj(obj, o.Out)
|
return printer.PrintObj(obj, o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOpts := o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
deleteOpts := o.DeleteFlags.ToOptions(o.IOStreams)
|
||||||
|
|
||||||
//Replace will create a resource if it doesn't exist already, so ignore not found error
|
//Replace will create a resource if it doesn't exist already, so ignore not found error
|
||||||
deleteOpts.IgnoreNotFound = true
|
deleteOpts.IgnoreNotFound = true
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -26,6 +25,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -63,9 +63,9 @@ func TestReplaceObject(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdReplace(tf, buf, buf)
|
cmd := NewCmdReplace(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
cmd.Run(cmd, []string{})
|
cmd.Run(cmd, []string{})
|
||||||
@ -134,9 +134,9 @@ func TestReplaceMultipleObject(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdReplace(tf, buf, buf)
|
cmd := NewCmdReplace(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -192,9 +192,9 @@ func TestReplaceDirectory(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdReplace(tf, buf, buf)
|
cmd := NewCmdReplace(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
||||||
cmd.Flags().Set("namespace", "test")
|
cmd.Flags().Set("namespace", "test")
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
@ -239,9 +239,9 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdReplace(tf, buf, buf)
|
cmd := NewCmdReplace(tf, streams)
|
||||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||||
cmd.Flags().Set("force", "true")
|
cmd.Flags().Set("force", "true")
|
||||||
cmd.Flags().Set("cascade", "false")
|
cmd.Flags().Set("cascade", "false")
|
||||||
|
@ -233,7 +233,7 @@ func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||||||
return printer.PrintObj(obj, o.Out)
|
return printer.PrintObj(obj, o.Out)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOpts := o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
deleteOpts := o.DeleteFlags.ToOptions(o.IOStreams)
|
||||||
deleteOpts.IgnoreNotFound = true
|
deleteOpts.IgnoreNotFound = true
|
||||||
deleteOpts.WaitForDeletion = false
|
deleteOpts.WaitForDeletion = false
|
||||||
deleteOpts.GracePeriod = -1
|
deleteOpts.GracePeriod = -1
|
||||||
@ -374,12 +374,10 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||||||
|
|
||||||
opts := &AttachOptions{
|
opts := &AttachOptions{
|
||||||
StreamOptions: StreamOptions{
|
StreamOptions: StreamOptions{
|
||||||
In: o.In,
|
IOStreams: o.IOStreams,
|
||||||
Out: o.Out,
|
Stdin: o.Interactive,
|
||||||
Err: o.ErrOut,
|
TTY: o.TTY,
|
||||||
Stdin: o.Interactive,
|
Quiet: o.Quiet,
|
||||||
TTY: o.TTY,
|
|
||||||
Quiet: o.Quiet,
|
|
||||||
},
|
},
|
||||||
GetPodTimeout: timeout,
|
GetPodTimeout: timeout,
|
||||||
CommandName: cmd.Parent().CommandPath() + " attach",
|
CommandName: cmd.Parent().CommandPath() + " attach",
|
||||||
@ -528,7 +526,7 @@ func handleAttachPod(f cmdutil.Factory, podClient coreclient.PodsGetter, ns, nam
|
|||||||
opts.Namespace = ns
|
opts.Namespace = ns
|
||||||
|
|
||||||
// TODO: opts.Run sets opts.Err to nil, we need to find a better way
|
// TODO: opts.Run sets opts.Err to nil, we need to find a better way
|
||||||
stderr := opts.Err
|
stderr := opts.ErrOut
|
||||||
if err := opts.Run(); err != nil {
|
if err := opts.Run(); err != nil {
|
||||||
fmt.Fprintf(stderr, "Error attaching, falling back to logs: %v\n", err)
|
fmt.Fprintf(stderr, "Error attaching, falling back to logs: %v\n", err)
|
||||||
return logOpts(f, pod, opts)
|
return logOpts(f, pod, opts)
|
||||||
|
@ -208,7 +208,7 @@ func TestRunArgsFollowDashRules(t *testing.T) {
|
|||||||
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
||||||
opts := &RunOptions{
|
opts := &RunOptions{
|
||||||
PrintFlags: printFlags,
|
PrintFlags: printFlags,
|
||||||
DeleteOptions: deleteFlags.ToOptions(os.Stdout, os.Stderr),
|
DeleteOptions: deleteFlags.ToOptions(genericclioptions.NewTestIOStreamsDiscard()),
|
||||||
|
|
||||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ func TestGenerateService(t *testing.T) {
|
|||||||
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
||||||
opts := &RunOptions{
|
opts := &RunOptions{
|
||||||
PrintFlags: printFlags,
|
PrintFlags: printFlags,
|
||||||
DeleteOptions: deleteFlags.ToOptions(os.Stdout, os.Stderr),
|
DeleteOptions: deleteFlags.ToOptions(genericclioptions.NewTestIOStreamsDiscard()),
|
||||||
|
|
||||||
IOStreams: ioStreams,
|
IOStreams: ioStreams,
|
||||||
|
|
||||||
|
@ -17,8 +17,6 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
@ -26,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -40,17 +39,17 @@ var (
|
|||||||
This command requires Heapster to be correctly configured and working on the server. `))
|
This command requires Heapster to be correctly configured and working on the server. `))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdTop(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdTop(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "top",
|
Use: "top",
|
||||||
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage."),
|
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage."),
|
||||||
Long: topLong,
|
Long: topLong,
|
||||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
Run: cmdutil.DefaultSubCommandRun(streams.ErrOut),
|
||||||
}
|
}
|
||||||
|
|
||||||
// create subcommands
|
// create subcommands
|
||||||
cmd.AddCommand(NewCmdTopNode(f, nil, out))
|
cmd.AddCommand(NewCmdTopNode(f, nil, streams))
|
||||||
cmd.AddCommand(NewCmdTopPod(f, nil, out))
|
cmd.AddCommand(NewCmdTopPod(f, nil, streams))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@ -29,6 +28,7 @@ import (
|
|||||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
||||||
@ -46,6 +46,8 @@ type TopNodeOptions struct {
|
|||||||
Printer *metricsutil.TopCmdPrinter
|
Printer *metricsutil.TopCmdPrinter
|
||||||
DiscoveryClient discovery.DiscoveryInterface
|
DiscoveryClient discovery.DiscoveryInterface
|
||||||
MetricsClient metricsclientset.Interface
|
MetricsClient metricsclientset.Interface
|
||||||
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
type HeapsterTopOptions struct {
|
type HeapsterTopOptions struct {
|
||||||
@ -89,9 +91,11 @@ var (
|
|||||||
kubectl top node NODE_NAME`))
|
kubectl top node NODE_NAME`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdTopNode(f cmdutil.Factory, options *TopNodeOptions, out io.Writer) *cobra.Command {
|
func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
if options == nil {
|
if o == nil {
|
||||||
options = &TopNodeOptions{}
|
o = &TopNodeOptions{
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -101,24 +105,24 @@ func NewCmdTopNode(f cmdutil.Factory, options *TopNodeOptions, out io.Writer) *c
|
|||||||
Long: topNodeLong,
|
Long: topNodeLong,
|
||||||
Example: topNodeExample,
|
Example: topNodeExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := options.Complete(f, cmd, args, out); err != nil {
|
if err := o.Complete(f, cmd, args); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := o.Validate(); err != nil {
|
||||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
||||||
}
|
}
|
||||||
if err := options.RunTopNode(); err != nil {
|
if err := o.RunTopNode(); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Aliases: []string{"nodes", "no"},
|
Aliases: []string{"nodes", "no"},
|
||||||
}
|
}
|
||||||
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||||
options.HeapsterOptions.Bind(cmd.Flags())
|
o.HeapsterOptions.Bind(cmd.Flags())
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
|
func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
o.ResourceName = args[0]
|
o.ResourceName = args[0]
|
||||||
} else if len(args) > 1 {
|
} else if len(args) > 1 {
|
||||||
@ -144,7 +148,7 @@ func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||||||
o.NodeClient = clientset.CoreV1()
|
o.NodeClient = clientset.CoreV1()
|
||||||
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
||||||
|
|
||||||
o.Printer = metricsutil.NewTopCmdPrinter(out)
|
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||||
@ -79,9 +80,9 @@ func TestTopNodeAllMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
cmd.Run(cmd, []string{})
|
cmd.Run(cmd, []string{})
|
||||||
|
|
||||||
// Check the presence of node names in the output.
|
// Check the presence of node names in the output.
|
||||||
@ -132,7 +133,7 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
opts := &TopNodeOptions{
|
opts := &TopNodeOptions{
|
||||||
HeapsterOptions: HeapsterTopOptions{
|
HeapsterOptions: HeapsterTopOptions{
|
||||||
@ -140,8 +141,9 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
|
|||||||
Scheme: "https",
|
Scheme: "https",
|
||||||
Service: "custom-heapster-service",
|
Service: "custom-heapster-service",
|
||||||
},
|
},
|
||||||
|
IOStreams: streams,
|
||||||
}
|
}
|
||||||
cmd := NewCmdTopNode(tf, opts, buf)
|
cmd := NewCmdTopNode(tf, opts, streams)
|
||||||
cmd.Run(cmd, []string{})
|
cmd.Run(cmd, []string{})
|
||||||
|
|
||||||
// Check the presence of node names in the output.
|
// Check the presence of node names in the output.
|
||||||
@ -195,9 +197,9 @@ func TestTopNodeWithNameMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
cmd.Run(cmd, []string{expectedMetrics.Name})
|
cmd.Run(cmd, []string{expectedMetrics.Name})
|
||||||
|
|
||||||
// Check the presence of node names in the output.
|
// Check the presence of node names in the output.
|
||||||
@ -262,9 +264,9 @@ func TestTopNodeWithLabelSelectorMetrics(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
cmd.Flags().Set("selector", label)
|
cmd.Flags().Set("selector", label)
|
||||||
cmd.Run(cmd, []string{})
|
cmd.Run(cmd, []string{})
|
||||||
|
|
||||||
@ -315,14 +317,16 @@ func TestTopNodeAllMetricsFromMetricsServer(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
|
|
||||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||||
cmdOptions := &TopNodeOptions{}
|
cmdOptions := &TopNodeOptions{
|
||||||
if err := cmdOptions.Complete(tf, cmd, []string{}, buf); err != nil {
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
if err := cmdOptions.Complete(tf, cmd, []string{}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
cmdOptions.MetricsClient = fakemetricsClientset
|
cmdOptions.MetricsClient = fakemetricsClientset
|
||||||
@ -381,14 +385,16 @@ func TestTopNodeWithNameMetricsFromMetricsServer(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
|
|
||||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||||
cmdOptions := &TopNodeOptions{}
|
cmdOptions := &TopNodeOptions{
|
||||||
if err := cmdOptions.Complete(tf, cmd, []string{expectedMetrics.Name}, buf); err != nil {
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
if err := cmdOptions.Complete(tf, cmd, []string{expectedMetrics.Name}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
cmdOptions.MetricsClient = fakemetricsClientset
|
cmdOptions.MetricsClient = fakemetricsClientset
|
||||||
@ -458,15 +464,17 @@ func TestTopNodeWithLabelSelectorMetricsFromMetricsServer(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopNode(tf, nil, buf)
|
cmd := NewCmdTopNode(tf, nil, streams)
|
||||||
cmd.Flags().Set("selector", label)
|
cmd.Flags().Set("selector", label)
|
||||||
|
|
||||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||||
cmdOptions := &TopNodeOptions{}
|
cmdOptions := &TopNodeOptions{
|
||||||
if err := cmdOptions.Complete(tf, cmd, []string{}, buf); err != nil {
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
if err := cmdOptions.Complete(tf, cmd, []string{}); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
cmdOptions.MetricsClient = fakemetricsClientset
|
cmdOptions.MetricsClient = fakemetricsClientset
|
||||||
|
@ -19,7 +19,6 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
@ -37,6 +36,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TopPodOptions struct {
|
type TopPodOptions struct {
|
||||||
@ -51,6 +51,8 @@ type TopPodOptions struct {
|
|||||||
Printer *metricsutil.TopCmdPrinter
|
Printer *metricsutil.TopCmdPrinter
|
||||||
DiscoveryClient discovery.DiscoveryInterface
|
DiscoveryClient discovery.DiscoveryInterface
|
||||||
MetricsClient metricsclientset.Interface
|
MetricsClient metricsclientset.Interface
|
||||||
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
const metricsCreationDelay = 2 * time.Minute
|
const metricsCreationDelay = 2 * time.Minute
|
||||||
@ -78,9 +80,11 @@ var (
|
|||||||
kubectl top pod -l name=myLabel`))
|
kubectl top pod -l name=myLabel`))
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdTopPod(f cmdutil.Factory, options *TopPodOptions, out io.Writer) *cobra.Command {
|
func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
if options == nil {
|
if o == nil {
|
||||||
options = &TopPodOptions{}
|
o = &TopPodOptions{
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -90,26 +94,26 @@ func NewCmdTopPod(f cmdutil.Factory, options *TopPodOptions, out io.Writer) *cob
|
|||||||
Long: topPodLong,
|
Long: topPodLong,
|
||||||
Example: topPodExample,
|
Example: topPodExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := options.Complete(f, cmd, args, out); err != nil {
|
if err := o.Complete(f, cmd, args); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
if err := options.Validate(); err != nil {
|
if err := o.Validate(); err != nil {
|
||||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
||||||
}
|
}
|
||||||
if err := options.RunTopPod(); err != nil {
|
if err := o.RunTopPod(); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Aliases: []string{"pods", "po"},
|
Aliases: []string{"pods", "po"},
|
||||||
}
|
}
|
||||||
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||||
cmd.Flags().BoolVar(&options.PrintContainers, "containers", options.PrintContainers, "If present, print usage of containers within a pod.")
|
cmd.Flags().BoolVar(&o.PrintContainers, "containers", o.PrintContainers, "If present, print usage of containers within a pod.")
|
||||||
cmd.Flags().BoolVar(&options.AllNamespaces, "all-namespaces", options.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
cmd.Flags().BoolVar(&o.AllNamespaces, "all-namespaces", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||||
options.HeapsterOptions.Bind(cmd.Flags())
|
o.HeapsterOptions.Bind(cmd.Flags())
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
|
func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||||
var err error
|
var err error
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
o.ResourceName = args[0]
|
o.ResourceName = args[0]
|
||||||
@ -139,7 +143,7 @@ func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||||||
o.PodClient = clientset.CoreV1()
|
o.PodClient = clientset.CoreV1()
|
||||||
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
||||||
|
|
||||||
o.Printer = metricsutil.NewTopCmdPrinter(out)
|
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ import (
|
|||||||
core "k8s.io/client-go/testing"
|
core "k8s.io/client-go/testing"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||||
metricsfake "k8s.io/metrics/pkg/client/clientset_generated/clientset/fake"
|
metricsfake "k8s.io/metrics/pkg/client/clientset_generated/clientset/fake"
|
||||||
@ -191,9 +192,9 @@ func TestTopPod(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = testNS
|
tf.Namespace = testNS
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopPod(tf, nil, buf)
|
cmd := NewCmdTopPod(tf, nil, streams)
|
||||||
for name, value := range testCase.flags {
|
for name, value := range testCase.flags {
|
||||||
cmd.Flags().Set(name, value)
|
cmd.Flags().Set(name, value)
|
||||||
}
|
}
|
||||||
@ -330,19 +331,20 @@ func TestTopPodWithMetricsServer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = testNS
|
tf.Namespace = testNS
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
cmd := NewCmdTopPod(tf, nil, buf)
|
cmd := NewCmdTopPod(tf, nil, streams)
|
||||||
var cmdOptions *TopPodOptions
|
var cmdOptions *TopPodOptions
|
||||||
if testCase.options != nil {
|
if testCase.options != nil {
|
||||||
cmdOptions = testCase.options
|
cmdOptions = testCase.options
|
||||||
} else {
|
} else {
|
||||||
cmdOptions = &TopPodOptions{}
|
cmdOptions = &TopPodOptions{}
|
||||||
}
|
}
|
||||||
|
cmdOptions.IOStreams = streams
|
||||||
|
|
||||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||||
// TODO then check the particular Run functionality and harvest results from fake clients. We probably end up skipping the factory altogether.
|
// TODO then check the particular Run functionality and harvest results from fake clients. We probably end up skipping the factory altogether.
|
||||||
if err := cmdOptions.Complete(tf, cmd, testCase.args, buf); err != nil {
|
if err := cmdOptions.Complete(tf, cmd, testCase.args); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
cmdOptions.MetricsClient = fakemetricsClientset
|
cmdOptions.MetricsClient = fakemetricsClientset
|
||||||
@ -534,7 +536,7 @@ func TestTopPodCustomDefaults(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tf.Namespace = testNS
|
tf.Namespace = testNS
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
opts := &TopPodOptions{
|
opts := &TopPodOptions{
|
||||||
HeapsterOptions: HeapsterTopOptions{
|
HeapsterOptions: HeapsterTopOptions{
|
||||||
@ -543,8 +545,9 @@ func TestTopPodCustomDefaults(t *testing.T) {
|
|||||||
Service: "custom-heapster-service",
|
Service: "custom-heapster-service",
|
||||||
},
|
},
|
||||||
DiscoveryClient: &fakeDiscovery{},
|
DiscoveryClient: &fakeDiscovery{},
|
||||||
|
IOStreams: streams,
|
||||||
}
|
}
|
||||||
cmd := NewCmdTopPod(tf, opts, buf)
|
cmd := NewCmdTopPod(tf, opts, streams)
|
||||||
for name, value := range testCase.flags {
|
for name, value := range testCase.flags {
|
||||||
cmd.Flags().Set(name, value)
|
cmd.Flags().Set(name, value)
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||||
)
|
)
|
||||||
@ -46,9 +47,7 @@ func TestTopSubcommandsExist(t *testing.T) {
|
|||||||
f := cmdtesting.NewTestFactory()
|
f := cmdtesting.NewTestFactory()
|
||||||
defer f.Cleanup()
|
defer f.Cleanup()
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
cmd := NewCmdTop(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||||
|
|
||||||
cmd := NewCmdTop(f, buf, buf)
|
|
||||||
if !cmd.HasSubCommands() {
|
if !cmd.HasSubCommands() {
|
||||||
t.Error("top command should have subcommands")
|
t.Error("top command should have subcommands")
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ go_library(
|
|||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/pkg/kubectl/plugins",
|
importpath = "k8s.io/kubernetes/pkg/kubectl/plugins",
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
@ -45,5 +46,8 @@ go_test(
|
|||||||
"runner_test.go",
|
"runner_test.go",
|
||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = ["//vendor/github.com/spf13/pflag:go_default_library"],
|
deps = [
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PluginRunner is capable of running a plugin in a given running context.
|
// PluginRunner is capable of running a plugin in a given running context.
|
||||||
@ -34,9 +34,7 @@ type PluginRunner interface {
|
|||||||
// in, out, and err streams, arguments and environment passed to it, and the
|
// in, out, and err streams, arguments and environment passed to it, and the
|
||||||
// working directory.
|
// working directory.
|
||||||
type RunningContext struct {
|
type RunningContext struct {
|
||||||
In io.Reader
|
genericclioptions.IOStreams
|
||||||
Out io.Writer
|
|
||||||
ErrOut io.Writer
|
|
||||||
Args []string
|
Args []string
|
||||||
EnvProvider EnvProvider
|
EnvProvider EnvProvider
|
||||||
WorkingDir string
|
WorkingDir string
|
||||||
|
@ -17,9 +17,10 @@ limitations under the License.
|
|||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExecRunner(t *testing.T) {
|
func TestExecRunner(t *testing.T) {
|
||||||
@ -50,7 +51,7 @@ func TestExecRunner(t *testing.T) {
|
|||||||
defer os.Unsetenv("KUBECTL_PLUGINS_TEST")
|
defer os.Unsetenv("KUBECTL_PLUGINS_TEST")
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
outBuf := bytes.NewBuffer([]byte{})
|
streams, _, outBuf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
|
||||||
plugin := &Plugin{
|
plugin := &Plugin{
|
||||||
Description: Description{
|
Description: Description{
|
||||||
@ -61,7 +62,7 @@ func TestExecRunner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx := RunningContext{
|
ctx := RunningContext{
|
||||||
Out: outBuf,
|
IOStreams: streams,
|
||||||
WorkingDir: ".",
|
WorkingDir: ".",
|
||||||
EnvProvider: &EmptyEnvProvider{},
|
EnvProvider: &EmptyEnvProvider{},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user