Unverified Commit 9c58985a authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #66519 from juanvallejo/jvallejo/switch-attch-externals

Automatic merge from submit-queue (batch tested with PRs 65730, 66615, 66684, 66519, 66510). 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>. update attach to use external objs **Release note**: ```release-note NONE ``` Updates attach command to use external versions. cc @deads2k @soltysh
parents 695d4fb5 3a3633a3
...@@ -59,7 +59,7 @@ go_library( ...@@ -59,7 +59,7 @@ go_library(
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/certificates:go_default_library", "//pkg/apis/certificates:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/validation:go_default_library", "//pkg/apis/core/v1:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/batch/internalversion:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/batch/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
...@@ -196,7 +196,6 @@ go_test( ...@@ -196,7 +196,6 @@ go_test(
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/kubectl/cmd/create:go_default_library", "//pkg/kubectl/cmd/create:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
......
...@@ -25,11 +25,10 @@ import ( ...@@ -25,11 +25,10 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
api "k8s.io/kubernetes/pkg/apis/core"
"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/genericclioptions"
...@@ -80,6 +79,24 @@ type LogsOptions struct { ...@@ -80,6 +79,24 @@ type LogsOptions struct {
ResourceArg string ResourceArg string
AllContainers bool AllContainers bool
Options runtime.Object Options runtime.Object
Resources []string
ConsumeRequestFn func(*rest.Request, io.Writer) error
// PodLogOptions
SinceTime string
SinceSeconds time.Duration
Follow bool
Previous bool
Timestamps bool
LimitBytes int64
Tail int64
Container string
// whether or not a container name was given via --container
ContainerNameSpecified bool
Interactive bool
Selector string
Object runtime.Object Object runtime.Object
GetPodTimeout time.Duration GetPodTimeout time.Duration
...@@ -93,6 +110,7 @@ func NewLogsOptions(streams genericclioptions.IOStreams, allContainers bool) *Lo ...@@ -93,6 +110,7 @@ func NewLogsOptions(streams genericclioptions.IOStreams, allContainers bool) *Lo
return &LogsOptions{ return &LogsOptions{
IOStreams: streams, IOStreams: streams,
AllContainers: allContainers, AllContainers: allContainers,
Tail: -1,
} }
} }
...@@ -119,40 +137,74 @@ func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C ...@@ -119,40 +137,74 @@ func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
Aliases: []string{"log"}, Aliases: []string{"log"},
} }
cmd.Flags().BoolVar(&o.AllContainers, "all-containers", o.AllContainers, "Get all containers's logs in the pod(s).") cmd.Flags().BoolVar(&o.AllContainers, "all-containers", o.AllContainers, "Get all containers's logs in the pod(s).")
cmd.Flags().BoolP("follow", "f", false, "Specify if the logs should be streamed.") cmd.Flags().BoolVarP(&o.Follow, "follow", "f", o.Follow, "Specify if the logs should be streamed.")
cmd.Flags().Bool("timestamps", false, "Include timestamps on each line in the log output") cmd.Flags().BoolVar(&o.Timestamps, "timestamps", o.Timestamps, "Include timestamps on each line in the log output")
cmd.Flags().Int64("limit-bytes", 0, "Maximum bytes of logs to return. Defaults to no limit.") cmd.Flags().Int64Var(&o.LimitBytes, "limit-bytes", o.LimitBytes, "Maximum bytes of logs to return. Defaults to no limit.")
cmd.Flags().BoolP("previous", "p", false, "If true, print the logs for the previous instance of the container in a pod if it exists.") cmd.Flags().BoolVarP(&o.Previous, "previous", "p", o.Previous, "If true, print the logs for the previous instance of the container in a pod if it exists.")
cmd.Flags().Int64("tail", -1, "Lines of recent log file to display. Defaults to -1 with no selector, showing all log lines otherwise 10, if a selector is provided.") cmd.Flags().Int64Var(&o.Tail, "tail", o.Tail, "Lines of recent log file to display. Defaults to -1 with no selector, showing all log lines otherwise 10, if a selector is provided.")
cmd.Flags().String("since-time", "", i18n.T("Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.")) cmd.Flags().StringVar(&o.SinceTime, "since-time", o.SinceTime, i18n.T("Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used."))
cmd.Flags().Duration("since", 0, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.") cmd.Flags().DurationVar(&o.SinceSeconds, "since", o.SinceSeconds, "Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used.")
cmd.Flags().StringP("container", "c", "", "Print the logs of this container") cmd.Flags().StringVarP(&o.Container, "container", "c", o.Container, "Print the logs of this container")
cmd.Flags().Bool("interactive", false, "If true, prompt the user for input when required.") cmd.Flags().BoolVar(&o.Interactive, "interactive", o.Interactive, "If true, prompt the user for input when required.")
cmd.Flags().MarkDeprecated("interactive", "This flag is no longer respected and there is no replacement.") cmd.Flags().MarkDeprecated("interactive", "This flag is no longer respected and there is no replacement.")
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodLogsTimeout) cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodLogsTimeout)
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on.") cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on.")
return cmd return cmd
} }
func (o *LogsOptions) ToLogOptions() (*corev1.PodLogOptions, error) {
logOptions := &corev1.PodLogOptions{
Container: o.Container,
Follow: o.Follow,
Previous: o.Previous,
Timestamps: o.Timestamps,
}
if len(o.SinceTime) > 0 {
t, err := util.ParseRFC3339(o.SinceTime, metav1.Now)
if err != nil {
return nil, err
}
logOptions.SinceTime = &t
}
if o.LimitBytes != 0 {
logOptions.LimitBytes = &o.LimitBytes
}
if o.SinceSeconds != 0 {
// round up to the nearest second
sec := int64(o.SinceSeconds.Round(time.Second).Seconds())
logOptions.SinceSeconds = &sec
}
if len(o.Selector) > 0 && o.Tail != -1 {
logOptions.TailLines = &selectorTail
} else if o.Tail != -1 {
logOptions.TailLines = &o.Tail
}
return logOptions, nil
}
func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
containerName := cmdutil.GetFlagString(cmd, "container") o.ContainerNameSpecified = cmd.Flag("container").Changed
selector := cmdutil.GetFlagString(cmd, "selector") o.Resources = args
switch len(args) { switch len(args) {
case 0: case 0:
if len(selector) == 0 { if len(o.Selector) == 0 {
return cmdutil.UsageErrorf(cmd, "%s", logsUsageStr) return cmdutil.UsageErrorf(cmd, "%s", logsUsageStr)
} }
case 1: case 1:
o.ResourceArg = args[0] o.ResourceArg = args[0]
if len(selector) != 0 { if len(o.Selector) != 0 {
return cmdutil.UsageErrorf(cmd, "only a selector (-l) or a POD name is allowed") return cmdutil.UsageErrorf(cmd, "only a selector (-l) or a POD name is allowed")
} }
case 2: case 2:
if cmd.Flag("container").Changed {
return cmdutil.UsageErrorf(cmd, "only one of -c or an inline [CONTAINER] arg is allowed")
}
o.ResourceArg = args[0] o.ResourceArg = args[0]
containerName = args[1] o.Container = args[1]
default: default:
return cmdutil.UsageErrorf(cmd, "%s", logsUsageStr) return cmdutil.UsageErrorf(cmd, "%s", logsUsageStr)
} }
...@@ -162,48 +214,21 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str ...@@ -162,48 +214,21 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
return err return err
} }
logOptions := &api.PodLogOptions{ o.ConsumeRequestFn = consumeRequest
Container: containerName,
Follow: cmdutil.GetFlagBool(cmd, "follow"),
Previous: cmdutil.GetFlagBool(cmd, "previous"),
Timestamps: cmdutil.GetFlagBool(cmd, "timestamps"),
}
if sinceTime := cmdutil.GetFlagString(cmd, "since-time"); len(sinceTime) > 0 {
t, err := util.ParseRFC3339(sinceTime, metav1.Now)
if err != nil {
return err
}
logOptions.SinceTime = &t
}
if limit := cmdutil.GetFlagInt64(cmd, "limit-bytes"); limit != 0 {
logOptions.LimitBytes = &limit
}
tail := cmdutil.GetFlagInt64(cmd, "tail")
if tail != -1 {
logOptions.TailLines = &tail
}
if sinceSeconds := cmdutil.GetFlagDuration(cmd, "since"); sinceSeconds != 0 {
// round up to the nearest second
sec := int64(sinceSeconds.Round(time.Second).Seconds())
logOptions.SinceSeconds = &sec
}
o.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd) o.GetPodTimeout, err = cmdutil.GetPodRunningTimeoutFlag(cmd)
if err != nil { if err != nil {
return err return err
} }
o.Options = logOptions
o.RESTClientGetter = f
o.LogsForObject = polymorphichelpers.LogsForObjectFn
if len(selector) != 0 { o.Options, err = o.ToLogOptions()
if logOptions.Follow { if err != nil {
return cmdutil.UsageErrorf(cmd, "only one of follow (-f) or selector (-l) is allowed") return err
}
if logOptions.TailLines == nil && tail != -1 {
logOptions.TailLines = &selectorTail
}
} }
o.RESTClientGetter = f
o.LogsForObject = polymorphichelpers.LogsForObjectFn
if o.Object == nil { if o.Object == nil {
builder := f.NewBuilder(). builder := f.NewBuilder().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...). WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
...@@ -212,14 +237,14 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str ...@@ -212,14 +237,14 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
if o.ResourceArg != "" { if o.ResourceArg != "" {
builder.ResourceNames("pods", o.ResourceArg) builder.ResourceNames("pods", o.ResourceArg)
} }
if selector != "" { if o.Selector != "" {
builder.ResourceTypes("pods").LabelSelectorParam(selector) builder.ResourceTypes("pods").LabelSelectorParam(o.Selector)
} }
infos, err := builder.Do().Infos() infos, err := builder.Do().Infos()
if err != nil { if err != nil {
return err return err
} }
if selector == "" && len(infos) != 1 { if o.Selector == "" && len(infos) != 1 {
return errors.New("expected a resource") return errors.New("expected a resource")
} }
o.Object = infos[0].Object o.Object = infos[0].Object
...@@ -229,15 +254,36 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str ...@@ -229,15 +254,36 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
} }
func (o LogsOptions) Validate() error { func (o LogsOptions) Validate() error {
logsOptions, ok := o.Options.(*api.PodLogOptions) if o.Follow && len(o.Selector) > 0 {
return fmt.Errorf("only one of follow (-f) or selector (-l) is allowed")
}
if len(o.SinceTime) > 0 && o.SinceSeconds != 0 {
return fmt.Errorf("at most one of `sinceTime` or `sinceSeconds` may be specified")
}
logsOptions, ok := o.Options.(*corev1.PodLogOptions)
if !ok { if !ok {
return errors.New("unexpected logs options object") return errors.New("unexpected logs options object")
} }
if o.AllContainers && len(logsOptions.Container) > 0 { if o.AllContainers && len(logsOptions.Container) > 0 {
return fmt.Errorf("--all-containers=true should not be specified with container name %s", logsOptions.Container) return fmt.Errorf("--all-containers=true should not be specified with container name %s", logsOptions.Container)
} }
if errs := validation.ValidatePodLogOptions(logsOptions); len(errs) > 0 {
return errs.ToAggregate() if o.ContainerNameSpecified && len(o.Resources) == 2 {
return fmt.Errorf("only one of -c or an inline [CONTAINER] arg is allowed")
}
if o.LimitBytes < 0 {
return fmt.Errorf("--limit-bytes must be greater than 0")
}
if logsOptions.SinceSeconds != nil && *logsOptions.SinceSeconds < int64(0) {
return fmt.Errorf("--since must be greater than 0")
}
if logsOptions.TailLines != nil && *logsOptions.TailLines < 0 {
return fmt.Errorf("TailLines must be greater than or equal to 0")
} }
return nil return nil
...@@ -251,7 +297,7 @@ func (o LogsOptions) RunLogs() error { ...@@ -251,7 +297,7 @@ func (o LogsOptions) RunLogs() error {
} }
for _, request := range requests { for _, request := range requests {
if err := consumeRequest(request, o.Out); err != nil { if err := o.ConsumeRequestFn(request, o.Out); err != nil {
return err return err
} }
} }
......
...@@ -34,6 +34,7 @@ import ( ...@@ -34,6 +34,7 @@ import (
"k8s.io/client-go/transport/spdy" "k8s.io/client-go/transport/spdy"
"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"
apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
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"
...@@ -210,7 +211,13 @@ func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg ...@@ -210,7 +211,13 @@ func (o *PortForwardOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
// handle service port mapping to target port if needed // handle service port mapping to target port if needed
switch t := obj.(type) { switch t := obj.(type) {
case *api.Service: case *api.Service:
o.Ports, err = translateServicePortToTargetPort(args[1:], *t, *forwardablePod) // TODO(juanvallejo): remove this once we convert this command to work with externals
internalPod := &api.Pod{}
if err := apiv1.Convert_v1_Pod_To_core_Pod(forwardablePod, internalPod, nil); err != nil {
return err
}
o.Ports, err = translateServicePortToTargetPort(args[1:], *t, *internalPod)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -22,18 +22,20 @@ import ( ...@@ -22,18 +22,20 @@ import (
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/client-go/dynamic"
"github.com/golang/glog" "github.com/golang/glog"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
coreclientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"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"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"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"
...@@ -377,27 +379,27 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e ...@@ -377,27 +379,27 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
return err return err
} }
opts.Config = config opts.Config = config
opts.AttachFunc = defaultAttachFunc
clientset, err := f.ClientSet() clientset, err := kubernetes.NewForConfig(config)
if err != nil { if err != nil {
return err return err
} }
opts.PodClient = clientset.Core()
attachablePod, err := polymorphichelpers.AttachablePodForObjectFn(f, runObject.Object, opts.GetPodTimeout) attachablePod, err := polymorphichelpers.AttachablePodForObjectFn(f, runObject.Object, opts.GetPodTimeout)
if err != nil { if err != nil {
return err return err
} }
err = handleAttachPod(f, clientset.Core(), attachablePod.Namespace, attachablePod.Name, opts) err = handleAttachPod(f, clientset.CoreV1(), attachablePod.Namespace, attachablePod.Name, opts)
if err != nil { if err != nil {
return err return err
} }
var pod *api.Pod var pod *corev1.Pod
leaveStdinOpen := o.LeaveStdinOpen leaveStdinOpen := o.LeaveStdinOpen
waitForExitCode := !leaveStdinOpen && restartPolicy == api.RestartPolicyNever waitForExitCode := !leaveStdinOpen && restartPolicy == api.RestartPolicyNever
if waitForExitCode { if waitForExitCode {
pod, err = waitForPod(clientset.Core(), attachablePod.Namespace, attachablePod.Name, kubectl.PodCompleted) pod, err = waitForPod(clientset.CoreV1(), attachablePod.Namespace, attachablePod.Name, kubectl.PodCompleted)
if err != nil { if err != nil {
return err return err
} }
...@@ -409,9 +411,9 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e ...@@ -409,9 +411,9 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
} }
switch pod.Status.Phase { switch pod.Status.Phase {
case api.PodSucceeded: case corev1.PodSucceeded:
return nil return nil
case api.PodFailed: case corev1.PodFailed:
unknownRcErr := fmt.Errorf("pod %s/%s failed with unknown exit code", pod.Namespace, pod.Name) unknownRcErr := fmt.Errorf("pod %s/%s failed with unknown exit code", pod.Namespace, pod.Name)
if len(pod.Status.ContainerStatuses) == 0 || pod.Status.ContainerStatuses[0].State.Terminated == nil { if len(pod.Status.ContainerStatuses) == 0 || pod.Status.ContainerStatuses[0].State.Terminated == nil {
return unknownRcErr return unknownRcErr
...@@ -466,20 +468,20 @@ func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*R ...@@ -466,20 +468,20 @@ func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*R
} }
// waitForPod watches the given pod until the exitCondition is true // waitForPod watches the given pod until the exitCondition is true
func waitForPod(podClient coreclient.PodsGetter, ns, name string, exitCondition watch.ConditionFunc) (*api.Pod, error) { func waitForPod(podClient coreclientv1.PodsGetter, ns, name string, exitCondition watch.ConditionFunc) (*corev1.Pod, error) {
w, err := podClient.Pods(ns).Watch(metav1.SingleObject(metav1.ObjectMeta{Name: name})) w, err := podClient.Pods(ns).Watch(metav1.SingleObject(metav1.ObjectMeta{Name: name}))
if err != nil { if err != nil {
return nil, err return nil, err
} }
intr := interrupt.New(nil, w.Stop) intr := interrupt.New(nil, w.Stop)
var result *api.Pod var result *corev1.Pod
err = intr.Run(func() error { err = intr.Run(func() error {
ev, err := watch.Until(0, w, func(ev watch.Event) (bool, error) { ev, err := watch.Until(0, w, func(ev watch.Event) (bool, error) {
return exitCondition(ev) return exitCondition(ev)
}) })
if ev != nil { if ev != nil {
result = ev.Object.(*api.Pod) result = ev.Object.(*corev1.Pod)
} }
return err return err
}) })
...@@ -492,37 +494,39 @@ func waitForPod(podClient coreclient.PodsGetter, ns, name string, exitCondition ...@@ -492,37 +494,39 @@ func waitForPod(podClient coreclient.PodsGetter, ns, name string, exitCondition
return result, err return result, err
} }
func handleAttachPod(f cmdutil.Factory, podClient coreclient.PodsGetter, ns, name string, opts *AttachOptions) error { func handleAttachPod(f cmdutil.Factory, podClient coreclientv1.PodsGetter, ns, name string, opts *AttachOptions) error {
pod, err := waitForPod(podClient, ns, name, kubectl.PodRunningAndReady) pod, err := waitForPod(podClient, ns, name, kubectl.PodRunningAndReady)
if err != nil && err != kubectl.ErrPodCompleted { if err != nil && err != kubectl.ErrPodCompleted {
return err return err
} }
if pod.Status.Phase == api.PodSucceeded || pod.Status.Phase == api.PodFailed { if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodFailed {
return logOpts(f, pod, opts) return logOpts(f, pod, opts)
} }
opts.PodClient = podClient opts.Pod = pod
opts.PodName = name opts.PodName = name
opts.Namespace = ns opts.Namespace = ns
// TODO: opts.Run sets opts.Err to nil, we need to find a better way if opts.AttachFunc == nil {
stderr := opts.ErrOut opts.AttachFunc = defaultAttachFunc
}
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(opts.ErrOut, "Error attaching, falling back to logs: %v\n", err)
return logOpts(f, pod, opts) return logOpts(f, pod, opts)
} }
return nil return nil
} }
// logOpts logs output from opts to the pods log. // logOpts logs output from opts to the pods log.
func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *api.Pod, opts *AttachOptions) error { func logOpts(restClientGetter genericclioptions.RESTClientGetter, pod *corev1.Pod, opts *AttachOptions) error {
ctrName, err := opts.GetContainerName(pod) ctrName, err := opts.GetContainerName(pod)
if err != nil { if err != nil {
return err return err
} }
requests, err := polymorphichelpers.LogsForObjectFn(restClientGetter, pod, &api.PodLogOptions{Container: ctrName}, opts.GetPodTimeout, false) requests, err := polymorphichelpers.LogsForObjectFn(restClientGetter, pod, &corev1.PodLogOptions{Container: ctrName}, opts.GetPodTimeout, false)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -19,12 +19,14 @@ package kubectl ...@@ -19,12 +19,14 @@ package kubectl
import ( import (
"fmt" "fmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/api/pod" "k8s.io/kubernetes/pkg/api/pod"
podv1 "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
...@@ -140,6 +142,13 @@ func PodRunning(event watch.Event) (bool, error) { ...@@ -140,6 +142,13 @@ func PodRunning(event watch.Event) (bool, error) {
case api.PodFailed, api.PodSucceeded: case api.PodFailed, api.PodSucceeded:
return false, ErrPodCompleted return false, ErrPodCompleted
} }
case *corev1.Pod:
switch t.Status.Phase {
case corev1.PodRunning:
return true, nil
case corev1.PodFailed, corev1.PodSucceeded:
return false, ErrPodCompleted
}
} }
return false, nil return false, nil
} }
...@@ -157,6 +166,11 @@ func PodCompleted(event watch.Event) (bool, error) { ...@@ -157,6 +166,11 @@ func PodCompleted(event watch.Event) (bool, error) {
case api.PodFailed, api.PodSucceeded: case api.PodFailed, api.PodSucceeded:
return true, nil return true, nil
} }
case *corev1.Pod:
switch t.Status.Phase {
case corev1.PodFailed, corev1.PodSucceeded:
return true, nil
}
} }
return false, nil return false, nil
} }
...@@ -177,6 +191,13 @@ func PodRunningAndReady(event watch.Event) (bool, error) { ...@@ -177,6 +191,13 @@ func PodRunningAndReady(event watch.Event) (bool, error) {
case api.PodRunning: case api.PodRunning:
return pod.IsPodReady(t), nil return pod.IsPodReady(t), nil
} }
case *corev1.Pod:
switch t.Status.Phase {
case corev1.PodFailed, corev1.PodSucceeded:
return false, ErrPodCompleted
case corev1.PodRunning:
return podv1.IsPodReady(t), nil
}
} }
return false, nil return false, nil
} }
......
...@@ -28,8 +28,6 @@ go_library( ...@@ -28,8 +28,6 @@ go_library(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/v1:go_default_library", "//pkg/apis/core/v1:go_default_library",
"//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/kubectl:go_default_library", "//pkg/kubectl:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library", "//pkg/kubectl/genericclioptions:go_default_library",
...@@ -49,6 +47,7 @@ go_library( ...@@ -49,6 +47,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/rest:go_default_library",
], ],
) )
...@@ -73,7 +72,6 @@ go_test( ...@@ -73,7 +72,6 @@ go_test(
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library", "//staging/src/k8s.io/api/apps/v1:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library", "//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
...@@ -90,6 +88,7 @@ go_test( ...@@ -90,6 +88,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
], ],
) )
......
...@@ -24,30 +24,29 @@ import ( ...@@ -24,30 +24,29 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
apiv1 "k8s.io/kubernetes/pkg/apis/core/v1" apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
// attachablePodForObject returns the pod to which to attach given an object. // attachablePodForObject returns the pod to which to attach given an object.
func attachablePodForObject(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*api.Pod, error) { func attachablePodForObject(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*corev1.Pod, error) {
switch t := object.(type) { switch t := object.(type) {
case *api.Pod: case *api.Pod:
return t, nil externalPod := &corev1.Pod{}
err := apiv1.Convert_core_Pod_To_v1_Pod(t, externalPod, nil)
return externalPod, err
case *corev1.Pod: case *corev1.Pod:
internalPod := &api.Pod{} return t, nil
err := apiv1.Convert_v1_Pod_To_core_Pod(t, internalPod, nil)
return internalPod, err
} }
clientConfig, err := restClientGetter.ToRESTConfig() clientConfig, err := restClientGetter.ToRESTConfig()
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset, err := internalclientset.NewForConfig(clientConfig) clientset, err := corev1client.NewForConfig(clientConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
...@@ -57,6 +56,6 @@ func attachablePodForObject(restClientGetter genericclioptions.RESTClientGetter, ...@@ -57,6 +56,6 @@ func attachablePodForObject(restClientGetter genericclioptions.RESTClientGetter,
return nil, fmt.Errorf("cannot attach to %T: %v", object, err) return nil, fmt.Errorf("cannot attach to %T: %v", object, err)
} }
sortBy := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) } sortBy := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }
pod, _, err := GetFirstPod(clientset.Core(), namespace, selector.String(), timeout, sortBy) pod, _, err := GetFirstPod(clientset, namespace, selector.String(), timeout, sortBy)
return pod, err return pod, err
} }
...@@ -32,17 +32,16 @@ import ( ...@@ -32,17 +32,16 @@ import (
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
coreclient "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
apiv1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
) )
// GetFirstPod returns a pod matching the namespace and label selector // GetFirstPod returns a pod matching the namespace and label selector
// and the number of all pods that match the label selector. // and the number of all pods that match the label selector.
func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string, timeout time.Duration, sortBy func([]*v1.Pod) sort.Interface) (*api.Pod, int, error) { func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string, timeout time.Duration, sortBy func([]*v1.Pod) sort.Interface) (*v1.Pod, int, error) {
options := metav1.ListOptions{LabelSelector: selector} options := metav1.ListOptions{LabelSelector: selector}
podList, err := client.Pods(namespace).List(options) podList, err := client.Pods(namespace).List(options)
...@@ -52,15 +51,11 @@ func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string ...@@ -52,15 +51,11 @@ func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string
pods := []*v1.Pod{} pods := []*v1.Pod{}
for i := range podList.Items { for i := range podList.Items {
pod := podList.Items[i] pod := podList.Items[i]
externalPod := &v1.Pod{} pods = append(pods, &pod)
apiv1.Convert_core_Pod_To_v1_Pod(&pod, externalPod, nil)
pods = append(pods, externalPod)
} }
if len(pods) > 0 { if len(pods) > 0 {
sort.Sort(sortBy(pods)) sort.Sort(sortBy(pods))
internalPod := &api.Pod{} return pods[0], len(podList.Items), nil
apiv1.Convert_v1_Pod_To_core_Pod(pods[0], internalPod, nil)
return internalPod, len(podList.Items), nil
} }
// Watch until we observe a pod // Watch until we observe a pod
...@@ -78,7 +73,7 @@ func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string ...@@ -78,7 +73,7 @@ func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string
if err != nil { if err != nil {
return nil, 0, err return nil, 0, err
} }
pod, ok := event.Object.(*api.Pod) pod, ok := event.Object.(*v1.Pod)
if !ok { if !ok {
return nil, 0, fmt.Errorf("%#v is not a pod event", event) return nil, 0, fmt.Errorf("%#v is not a pod event", event)
} }
......
...@@ -22,15 +22,14 @@ import ( ...@@ -22,15 +22,14 @@ import (
"testing" "testing"
"time" "time"
"k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
fakeexternal "k8s.io/client-go/kubernetes/fake"
testcore "k8s.io/client-go/testing" testcore "k8s.io/client-go/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
) )
...@@ -39,30 +38,30 @@ func TestGetFirstPod(t *testing.T) { ...@@ -39,30 +38,30 @@ func TestGetFirstPod(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
podList *api.PodList podList *corev1.PodList
watching []watch.Event watching []watch.Event
sortBy func([]*v1.Pod) sort.Interface sortBy func([]*corev1.Pod) sort.Interface
expected *api.Pod expected *corev1.Pod
expectedNum int expectedNum int
expectedErr bool expectedErr bool
}{ }{
{ {
name: "kubectl logs - two ready pods", name: "kubectl logs - two ready pods",
podList: newPodList(2, -1, -1, labelSet), podList: newPodList(2, -1, -1, labelSet),
sortBy: func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) }, sortBy: func(pods []*corev1.Pod) sort.Interface { return controller.ByLogging(pods) },
expected: &api.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pod-1", Name: "pod-1",
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC),
Labels: map[string]string{"test": "selector"}, Labels: map[string]string{"test": "selector"},
}, },
Status: api.PodStatus{ Status: corev1.PodStatus{
Conditions: []api.PodCondition{ Conditions: []corev1.PodCondition{
{ {
Status: api.ConditionTrue, Status: corev1.ConditionTrue,
Type: api.PodReady, Type: corev1.PodReady,
}, },
}, },
}, },
...@@ -72,22 +71,22 @@ func TestGetFirstPod(t *testing.T) { ...@@ -72,22 +71,22 @@ func TestGetFirstPod(t *testing.T) {
{ {
name: "kubectl logs - one unhealthy, one healthy", name: "kubectl logs - one unhealthy, one healthy",
podList: newPodList(2, -1, 1, labelSet), podList: newPodList(2, -1, 1, labelSet),
sortBy: func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) }, sortBy: func(pods []*corev1.Pod) sort.Interface { return controller.ByLogging(pods) },
expected: &api.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pod-2", Name: "pod-2",
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 1, 0, time.UTC), CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 1, 0, time.UTC),
Labels: map[string]string{"test": "selector"}, Labels: map[string]string{"test": "selector"},
}, },
Status: api.PodStatus{ Status: corev1.PodStatus{
Conditions: []api.PodCondition{ Conditions: []corev1.PodCondition{
{ {
Status: api.ConditionTrue, Status: corev1.ConditionTrue,
Type: api.PodReady, Type: corev1.PodReady,
}, },
}, },
ContainerStatuses: []api.ContainerStatus{{RestartCount: 5}}, ContainerStatuses: []corev1.ContainerStatus{{RestartCount: 5}},
}, },
}, },
expectedNum: 2, expectedNum: 2,
...@@ -95,19 +94,19 @@ func TestGetFirstPod(t *testing.T) { ...@@ -95,19 +94,19 @@ func TestGetFirstPod(t *testing.T) {
{ {
name: "kubectl attach - two ready pods", name: "kubectl attach - two ready pods",
podList: newPodList(2, -1, -1, labelSet), podList: newPodList(2, -1, -1, labelSet),
sortBy: func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, sortBy: func(pods []*corev1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) },
expected: &api.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pod-1", Name: "pod-1",
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC),
Labels: map[string]string{"test": "selector"}, Labels: map[string]string{"test": "selector"},
}, },
Status: api.PodStatus{ Status: corev1.PodStatus{
Conditions: []api.PodCondition{ Conditions: []corev1.PodCondition{
{ {
Status: api.ConditionTrue, Status: corev1.ConditionTrue,
Type: api.PodReady, Type: corev1.PodReady,
}, },
}, },
}, },
...@@ -138,19 +137,19 @@ func TestGetFirstPod(t *testing.T) { ...@@ -138,19 +137,19 @@ func TestGetFirstPod(t *testing.T) {
}, },
}, },
}, },
sortBy: func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, sortBy: func(pods []*corev1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) },
expected: &api.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "pod-1", Name: "pod-1",
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC), CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, 0, 0, time.UTC),
Labels: map[string]string{"test": "selector"}, Labels: map[string]string{"test": "selector"},
}, },
Status: api.PodStatus{ Status: corev1.PodStatus{
Conditions: []api.PodCondition{ Conditions: []corev1.PodCondition{
{ {
Status: api.ConditionTrue, Status: corev1.ConditionTrue,
Type: api.PodReady, Type: corev1.PodReady,
}, },
}, },
}, },
...@@ -161,7 +160,7 @@ func TestGetFirstPod(t *testing.T) { ...@@ -161,7 +160,7 @@ func TestGetFirstPod(t *testing.T) {
for i := range tests { for i := range tests {
test := tests[i] test := tests[i]
fake := fake.NewSimpleClientset(test.podList) fake := fakeexternal.NewSimpleClientset(test.podList)
if len(test.watching) > 0 { if len(test.watching) > 0 {
watcher := watch.NewFake() watcher := watch.NewFake()
for _, event := range test.watching { for _, event := range test.watching {
...@@ -196,21 +195,21 @@ func TestGetFirstPod(t *testing.T) { ...@@ -196,21 +195,21 @@ func TestGetFirstPod(t *testing.T) {
} }
} }
func newPodList(count, isUnready, isUnhealthy int, labels map[string]string) *api.PodList { func newPodList(count, isUnready, isUnhealthy int, labels map[string]string) *corev1.PodList {
pods := []api.Pod{} pods := []corev1.Pod{}
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
newPod := api.Pod{ newPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("pod-%d", i+1), Name: fmt.Sprintf("pod-%d", i+1),
Namespace: metav1.NamespaceDefault, Namespace: metav1.NamespaceDefault,
CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, i, 0, time.UTC), CreationTimestamp: metav1.Date(2016, time.April, 1, 1, 0, i, 0, time.UTC),
Labels: labels, Labels: labels,
}, },
Status: api.PodStatus{ Status: corev1.PodStatus{
Conditions: []api.PodCondition{ Conditions: []corev1.PodCondition{
{ {
Status: api.ConditionTrue, Status: corev1.ConditionTrue,
Type: api.PodReady, Type: corev1.PodReady,
}, },
}, },
}, },
...@@ -218,12 +217,12 @@ func newPodList(count, isUnready, isUnhealthy int, labels map[string]string) *ap ...@@ -218,12 +217,12 @@ func newPodList(count, isUnready, isUnhealthy int, labels map[string]string) *ap
pods = append(pods, newPod) pods = append(pods, newPod)
} }
if isUnready > -1 && isUnready < count { if isUnready > -1 && isUnready < count {
pods[isUnready].Status.Conditions[0].Status = api.ConditionFalse pods[isUnready].Status.Conditions[0].Status = corev1.ConditionFalse
} }
if isUnhealthy > -1 && isUnhealthy < count { if isUnhealthy > -1 && isUnhealthy < count {
pods[isUnhealthy].Status.ContainerStatuses = []api.ContainerStatus{{RestartCount: 5}} pods[isUnhealthy].Status.ContainerStatuses = []corev1.ContainerStatus{{RestartCount: 5}}
} }
return &api.PodList{ return &corev1.PodList{
Items: pods, Items: pods,
} }
} }
...@@ -24,7 +24,6 @@ import ( ...@@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
...@@ -36,7 +35,7 @@ type LogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter, ...@@ -36,7 +35,7 @@ type LogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter,
var LogsForObjectFn LogsForObjectFunc = logsForObject var LogsForObjectFn LogsForObjectFunc = logsForObject
// AttachableLogsForObjectFunc is a function type that can tell you how to get the pod for which to attach a given object // AttachableLogsForObjectFunc is a function type that can tell you how to get the pod for which to attach a given object
type AttachableLogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*api.Pod, error) type AttachableLogsForObjectFunc func(restClientGetter genericclioptions.RESTClientGetter, object runtime.Object, timeout time.Duration) (*v1.Pod, error)
// AttachablePodForObjectFn gives a way to easily override the function for unit testing if needed. // AttachablePodForObjectFn gives a way to easily override the function for unit testing if needed.
var AttachablePodForObjectFn AttachableLogsForObjectFunc = attachablePodForObject var AttachablePodForObjectFn AttachableLogsForObjectFunc = attachablePodForObject
......
...@@ -26,9 +26,9 @@ import ( ...@@ -26,9 +26,9 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
coreinternal "k8s.io/kubernetes/pkg/apis/core" coreinternal "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions" "k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
...@@ -38,16 +38,18 @@ func logsForObject(restClientGetter genericclioptions.RESTClientGetter, object, ...@@ -38,16 +38,18 @@ func logsForObject(restClientGetter genericclioptions.RESTClientGetter, object,
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset, err := internalclientset.NewForConfig(clientConfig)
clientset, err := corev1client.NewForConfig(clientConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return logsForObjectWithClient(clientset, object, options, timeout, allContainers) return logsForObjectWithClient(clientset, object, options, timeout, allContainers)
} }
// TODO: remove internal clientset once all callers use external versions
// this is split for easy test-ability // this is split for easy test-ability
func logsForObjectWithClient(clientset internalclientset.Interface, object, options runtime.Object, timeout time.Duration, allContainers bool) ([]*rest.Request, error) { func logsForObjectWithClient(clientset corev1client.CoreV1Interface, object, options runtime.Object, timeout time.Duration, allContainers bool) ([]*rest.Request, error) {
opts, ok := options.(*coreinternal.PodLogOptions) opts, ok := options.(*corev1.PodLogOptions)
if !ok { if !ok {
return nil, errors.New("provided options object is not a PodLogOptions") return nil, errors.New("provided options object is not a PodLogOptions")
} }
...@@ -78,7 +80,7 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti ...@@ -78,7 +80,7 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti
case *coreinternal.Pod: case *coreinternal.Pod:
// if allContainers is true, then we're going to locate all containers and then iterate through them. At that point, "allContainers" is false // if allContainers is true, then we're going to locate all containers and then iterate through them. At that point, "allContainers" is false
if !allContainers { if !allContainers {
return []*rest.Request{clientset.Core().Pods(t.Namespace).GetLogs(t.Name, opts)}, nil return []*rest.Request{clientset.Pods(t.Namespace).GetLogs(t.Name, opts)}, nil
} }
ret := []*rest.Request{} ret := []*rest.Request{}
...@@ -106,7 +108,7 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti ...@@ -106,7 +108,7 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti
case *corev1.Pod: case *corev1.Pod:
// if allContainers is true, then we're going to locate all containers and then iterate through them. At that point, "allContainers" is false // if allContainers is true, then we're going to locate all containers and then iterate through them. At that point, "allContainers" is false
if !allContainers { if !allContainers {
return []*rest.Request{clientset.Core().Pods(t.Namespace).GetLogs(t.Name, opts)}, nil return []*rest.Request{clientset.Pods(t.Namespace).GetLogs(t.Name, opts)}, nil
} }
ret := []*rest.Request{} ret := []*rest.Request{}
...@@ -136,8 +138,9 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti ...@@ -136,8 +138,9 @@ func logsForObjectWithClient(clientset internalclientset.Interface, object, opti
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot get the logs from %T: %v", object, err) return nil, fmt.Errorf("cannot get the logs from %T: %v", object, err)
} }
sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) } sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) }
pod, numPods, err := GetFirstPod(clientset.Core(), namespace, selector.String(), timeout, sortBy) pod, numPods, err := GetFirstPod(clientset, namespace, selector.String(), timeout, sortBy)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -21,34 +21,34 @@ import ( ...@@ -21,34 +21,34 @@ import (
"testing" "testing"
"time" "time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
fakeexternal "k8s.io/client-go/kubernetes/fake"
testclient "k8s.io/client-go/testing" testclient "k8s.io/client-go/testing"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
) )
var ( var (
podsResource = schema.GroupVersionResource{Resource: "pods"} podsResource = schema.GroupVersionResource{Version: "v1", Resource: "pods"}
podsKind = schema.GroupVersionKind{Kind: "Pod"} podsKind = schema.GroupVersionKind{Version: "v1", Kind: "Pod"}
) )
func TestLogsForObject(t *testing.T) { func TestLogsForObject(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
obj runtime.Object obj runtime.Object
opts *api.PodLogOptions opts *corev1.PodLogOptions
pods []runtime.Object pods []runtime.Object
actions []testclient.Action actions []testclient.Action
}{ }{
{ {
name: "pod logs", name: "pod logs",
obj: &api.Pod{ obj: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "hello", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "hello", Namespace: "test"},
}, },
pods: []runtime.Object{testPod()}, pods: []runtime.Object{testPod()},
...@@ -58,9 +58,9 @@ func TestLogsForObject(t *testing.T) { ...@@ -58,9 +58,9 @@ func TestLogsForObject(t *testing.T) {
}, },
{ {
name: "replication controller logs", name: "replication controller logs",
obj: &api.ReplicationController{ obj: &corev1.ReplicationController{
ObjectMeta: metav1.ObjectMeta{Name: "hello", Namespace: "test"}, ObjectMeta: metav1.ObjectMeta{Name: "hello", Namespace: "test"},
Spec: api.ReplicationControllerSpec{ Spec: corev1.ReplicationControllerSpec{
Selector: map[string]string{"foo": "bar"}, Selector: map[string]string{"foo": "bar"},
}, },
}, },
...@@ -129,8 +129,8 @@ func TestLogsForObject(t *testing.T) { ...@@ -129,8 +129,8 @@ func TestLogsForObject(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
fakeClientset := fake.NewSimpleClientset(test.pods...) fakeClientset := fakeexternal.NewSimpleClientset(test.pods...)
_, err := logsForObjectWithClient(fakeClientset, test.obj, test.opts, 20*time.Second, false) _, err := logsForObjectWithClient(fakeClientset.CoreV1(), test.obj, test.opts, 20*time.Second, false)
if err != nil { if err != nil {
t.Errorf("%s: unexpected error: %v", test.name, err) t.Errorf("%s: unexpected error: %v", test.name, err)
continue continue
...@@ -151,21 +151,21 @@ func TestLogsForObject(t *testing.T) { ...@@ -151,21 +151,21 @@ func TestLogsForObject(t *testing.T) {
} }
func testPod() runtime.Object { func testPod() runtime.Object {
return &api.Pod{ return &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: "test", Namespace: "test",
Labels: map[string]string{"foo": "bar"}, Labels: map[string]string{"foo": "bar"},
}, },
Spec: api.PodSpec{ Spec: corev1.PodSpec{
RestartPolicy: api.RestartPolicyAlways, RestartPolicy: corev1.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst, DNSPolicy: corev1.DNSClusterFirst,
Containers: []api.Container{{Name: "c1"}}, Containers: []corev1.Container{{Name: "c1"}},
}, },
} }
} }
func getLogsAction(namespace string, opts *api.PodLogOptions) testclient.Action { func getLogsAction(namespace string, opts *corev1.PodLogOptions) testclient.Action {
action := testclient.GenericActionImpl{} action := testclient.GenericActionImpl{}
action.Verb = "get" action.Verb = "get"
action.Namespace = namespace action.Namespace = namespace
......
...@@ -564,7 +564,7 @@ var _ = SIGDescribe("Kubectl client", func() { ...@@ -564,7 +564,7 @@ var _ = SIGDescribe("Kubectl client", func() {
ExecOrDie() ExecOrDie()
Expect(runOutput).ToNot(ContainSubstring("stdin closed")) Expect(runOutput).ToNot(ContainSubstring("stdin closed"))
g := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) } g := func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }
runTestPod, _, err := polymorphichelpers.GetFirstPod(f.InternalClientset.Core(), ns, "run=run-test-3", 1*time.Minute, g) runTestPod, _, err := polymorphichelpers.GetFirstPod(f.ClientSet.CoreV1(), ns, "run=run-test-3", 1*time.Minute, g)
if err != nil { if err != nil {
os.Exit(1) os.Exit(1)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment