update attach to use external objs

parent 4d5d2664
...@@ -59,6 +59,7 @@ go_library( ...@@ -59,6 +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/v1:go_default_library",
"//pkg/apis/core/validation:go_default_library", "//pkg/apis/core/validation: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",
......
...@@ -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