From 96cd71d8f64bb7897f18115f46986f514a0722f3 Mon Sep 17 00:00:00 2001 From: Chao Xu Date: Fri, 18 Nov 2016 12:58:22 -0800 Subject: [PATCH] kubectl --- .../deployment/util/deployment_util.go | 29 ++++++++++++++-- pkg/kubectl/cmd/util/factory.go | 23 ++++++++----- pkg/kubectl/cmd/util/factory_test.go | 12 ++++--- pkg/kubectl/describe.go | 17 ++++++---- pkg/kubectl/describe_test.go | 25 +++++++++----- pkg/kubectl/history.go | 14 +++++--- pkg/kubectl/rollback.go | 23 ++++++++++--- pkg/kubectl/rolling_updater.go | 7 +++- pkg/kubectl/rollout_status.go | 2 +- pkg/kubectl/sorted_resource_name_list.go | 2 +- pkg/kubectl/stop.go | 2 +- pkg/kubectl/stop_test.go | 4 +-- pkg/kubectl/versioned_client.go | 34 +++++++++++++++++++ 13 files changed, 149 insertions(+), 45 deletions(-) create mode 100644 pkg/kubectl/versioned_client.go diff --git a/pkg/controller/deployment/util/deployment_util.go b/pkg/controller/deployment/util/deployment_util.go index a75676d2f6..ab31de0293 100644 --- a/pkg/controller/deployment/util/deployment_util.go +++ b/pkg/controller/deployment/util/deployment_util.go @@ -132,6 +132,18 @@ func GetDeploymentCondition(status extensions.DeploymentStatus, condType extensi return nil } +// TODO: remove the duplicate +// GetDeploymentConditionInternal returns the condition with the provided type. +func GetDeploymentConditionInternal(status internalextensions.DeploymentStatus, condType internalextensions.DeploymentConditionType) *internalextensions.DeploymentCondition { + for i := range status.Conditions { + c := status.Conditions[i] + if c.Type == condType { + return &c + } + } + return nil +} + // SetDeploymentCondition updates the deployment to include the provided condition. If the condition that // we are about to add already exists and has the same status and reason then we are not going to update. func SetDeploymentCondition(status *extensions.DeploymentStatus, condition extensions.DeploymentCondition) { @@ -729,8 +741,8 @@ func GetNewReplicaSetTemplate(deployment *extensions.Deployment) v1.PodTemplateS } // TODO: remove the duplicate -// GetNewInternalReplicaSetTemplate returns the desired PodTemplateSpec for the new ReplicaSet corresponding to the given ReplicaSet. -func GetNewInternalReplicaSetTemplate(deployment *internalextensions.Deployment) api.PodTemplateSpec { +// GetNewReplicaSetTemplateInternal returns the desired PodTemplateSpec for the new ReplicaSet corresponding to the given ReplicaSet. +func GetNewReplicaSetTemplateInternal(deployment *internalextensions.Deployment) api.PodTemplateSpec { // newRS will have the same template as in deployment spec, plus a unique label in some cases. newRSTemplate := api.PodTemplateSpec{ ObjectMeta: deployment.Spec.Template.ObjectMeta, @@ -925,6 +937,19 @@ func WaitForObservedDeployment(getDeploymentFunc func() (*extensions.Deployment, }) } +// TODO: remove the duplicate +// WaitForObservedInternalDeployment polls for deployment to be updated so that deployment.Status.ObservedGeneration >= desiredGeneration. +// Returns error if polling timesout. +func WaitForObservedDeploymentInternal(getDeploymentFunc func() (*internalextensions.Deployment, error), desiredGeneration int64, interval, timeout time.Duration) error { + return wait.Poll(interval, timeout, func() (bool, error) { + deployment, err := getDeploymentFunc() + if err != nil { + return false, err + } + return deployment.Status.ObservedGeneration >= desiredGeneration, nil + }) +} + // ResolveFenceposts resolves both maxSurge and maxUnavailable. This needs to happen in one // step. For example: // diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index bd5dc14614..cfcd01083f 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -42,6 +42,7 @@ import ( "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apis/apps" @@ -596,7 +597,7 @@ func (f *factory) LogsForObject(object, options runtime.Object) (*restclient.Req return nil, errors.New("provided options object is not a PodLogOptions") } selector := labels.SelectorFromSet(t.Spec.Selector) - sortBy := func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) } + sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) } pod, numPods, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 20*time.Second, sortBy) if err != nil { return nil, err @@ -616,7 +617,7 @@ func (f *factory) LogsForObject(object, options runtime.Object) (*restclient.Req if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } - sortBy := func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) } + sortBy := func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) } pod, numPods, err := GetFirstPod(clientset.Core(), t.Namespace, selector, 20*time.Second, sortBy) if err != nil { return nil, err @@ -797,7 +798,7 @@ func (f *factory) AttachablePodForObject(object runtime.Object) (*api.Pod, error switch t := object.(type) { case *api.ReplicationController: selector := labels.SelectorFromSet(t.Spec.Selector) - sortBy := func(pods []*api.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(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *extensions.Deployment: @@ -805,7 +806,7 @@ func (f *factory) AttachablePodForObject(object runtime.Object) (*api.Pod, error if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } - sortBy := func(pods []*api.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(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *batch.Job: @@ -813,7 +814,7 @@ func (f *factory) AttachablePodForObject(object runtime.Object) (*api.Pod, error if err != nil { return nil, fmt.Errorf("invalid label selector: %v", err) } - sortBy := func(pods []*api.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(), t.Namespace, selector, 1*time.Minute, sortBy) return pod, err case *api.Pod: @@ -886,21 +887,25 @@ See http://kubernetes.io/docs/user-guide/services-firewalls for more details. // GetFirstPod returns a pod matching the namespace and label selector // and the number of all pods that match the label selector. -func GetFirstPod(client coreclient.PodsGetter, namespace string, selector labels.Selector, timeout time.Duration, sortBy func([]*api.Pod) sort.Interface) (*api.Pod, int, error) { +func GetFirstPod(client coreclient.PodsGetter, namespace string, selector labels.Selector, timeout time.Duration, sortBy func([]*v1.Pod) sort.Interface) (*api.Pod, int, error) { options := api.ListOptions{LabelSelector: selector} podList, err := client.Pods(namespace).List(options) if err != nil { return nil, 0, err } - pods := []*api.Pod{} + pods := []*v1.Pod{} for i := range podList.Items { pod := podList.Items[i] - pods = append(pods, &pod) + externalPod := &v1.Pod{} + v1.Convert_api_Pod_To_v1_Pod(&pod, externalPod, nil) + pods = append(pods, externalPod) } if len(pods) > 0 { sort.Sort(sortBy(pods)) - return pods[0], len(podList.Items), nil + internalPod := &api.Pod{} + v1.Convert_v1_Pod_To_api_Pod(pods[0], internalPod, nil) + return internalPod, len(podList.Items), nil } // Watch until we observe a pod diff --git a/pkg/kubectl/cmd/util/factory_test.go b/pkg/kubectl/cmd/util/factory_test.go index c5980bdafe..b53bb2bb5d 100644 --- a/pkg/kubectl/cmd/util/factory_test.go +++ b/pkg/kubectl/cmd/util/factory_test.go @@ -35,6 +35,7 @@ import ( "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apis/extensions" @@ -471,7 +472,7 @@ func TestGetFirstPod(t *testing.T) { podList *api.PodList watching []watch.Event - sortBy func([]*api.Pod) sort.Interface + sortBy func([]*v1.Pod) sort.Interface expected *api.Pod expectedNum int @@ -480,7 +481,7 @@ func TestGetFirstPod(t *testing.T) { { name: "kubectl logs - two ready pods", podList: newPodList(2, -1, -1, labelSet), - sortBy: func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }, + sortBy: func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", @@ -502,7 +503,7 @@ func TestGetFirstPod(t *testing.T) { { name: "kubectl logs - one unhealthy, one healthy", podList: newPodList(2, -1, 1, labelSet), - sortBy: func(pods []*api.Pod) sort.Interface { return controller.ByLogging(pods) }, + sortBy: func(pods []*v1.Pod) sort.Interface { return controller.ByLogging(pods) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-2", @@ -525,7 +526,7 @@ func TestGetFirstPod(t *testing.T) { { name: "kubectl attach - two ready pods", podList: newPodList(2, -1, -1, labelSet), - sortBy: func(pods []*api.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, + sortBy: func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", @@ -568,7 +569,7 @@ func TestGetFirstPod(t *testing.T) { }, }, }, - sortBy: func(pods []*api.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, + sortBy: func(pods []*v1.Pod) sort.Interface { return sort.Reverse(controller.ActivePods(pods)) }, expected: &api.Pod{ ObjectMeta: api.ObjectMeta{ Name: "pod-1", @@ -607,6 +608,7 @@ func TestGetFirstPod(t *testing.T) { selector := labels.Set(labelSet).AsSelector() pod, numPods, err := GetFirstPod(fake.Core(), api.NamespaceDefault, selector, 1*time.Minute, test.sortBy) + pod.Spec.SecurityContext = nil if !test.expectedErr && err != nil { t.Errorf("%s: unexpected error: %v", test.name, err) continue diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index 023313aa6f..503db1bb7d 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -40,12 +40,14 @@ import ( "k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/extensions" + versionedextension "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/storage" storageutil "k8s.io/kubernetes/pkg/apis/storage/util" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" extensionsclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion" + versionedclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" "k8s.io/kubernetes/pkg/fieldpath" "k8s.io/kubernetes/pkg/fields" @@ -113,7 +115,7 @@ func describerMap(c clientset.Interface) map[unversioned.GroupKind]Describer { extensions.Kind("NetworkPolicy"): &NetworkPolicyDescriber{c}, autoscaling.Kind("HorizontalPodAutoscaler"): &HorizontalPodAutoscalerDescriber{c}, extensions.Kind("DaemonSet"): &DaemonSetDescriber{c}, - extensions.Kind("Deployment"): &DeploymentDescriber{c}, + extensions.Kind("Deployment"): &DeploymentDescriber{c, versionedClientsetForDeployment(c)}, extensions.Kind("Job"): &JobDescriber{c}, extensions.Kind("Ingress"): &IngressDescriber{c}, batch.Kind("Job"): &JobDescriber{c}, @@ -505,7 +507,7 @@ func describePod(pod *api.Pod, events *api.EventList) (string, error) { } } describeVolumes(pod.Spec.Volumes, out, "") - fmt.Fprintf(out, "QoS Class:\t%s\n", qos.GetPodQOS(pod)) + fmt.Fprintf(out, "QoS Class:\t%s\n", qos.InternalGetPodQOS(pod)) printTolerationsInAnnotationMultiline(out, "Tolerations", pod.Annotations) if events != nil { DescribeEvents(events, out) @@ -955,7 +957,7 @@ func describeContainers(label string, containers []api.Container, containerStatu } fmt.Fprintf(out, " %s:\t%s (%s:%s)\n", e.Name, valueFrom, e.ValueFrom.FieldRef.APIVersion, e.ValueFrom.FieldRef.FieldPath) case e.ValueFrom.ResourceFieldRef != nil: - valueFrom, err := fieldpath.ExtractContainerResourceValue(e.ValueFrom.ResourceFieldRef, &container) + valueFrom, err := fieldpath.InternalExtractContainerResourceValue(e.ValueFrom.ResourceFieldRef, &container) if err != nil { valueFrom = "" } @@ -2152,10 +2154,11 @@ func DescribeEvents(el *api.EventList, w io.Writer) { // DeploymentDescriber generates information about a deployment. type DeploymentDescriber struct { clientset.Interface + versionedClient versionedclientset.Interface } func (dd *DeploymentDescriber) Describe(namespace, name string, describerSettings DescriberSettings) (string, error) { - d, err := dd.Extensions().Deployments(namespace).Get(name) + d, err := dd.versionedClient.Extensions().Deployments(namespace).Get(name) if err != nil { return "", err } @@ -2183,10 +2186,10 @@ func (dd *DeploymentDescriber) Describe(namespace, name string, describerSetting fmt.Fprintf(out, " %v \t%v\t%v\n", c.Type, c.Status, c.Reason) } } - oldRSs, _, newRS, err := deploymentutil.GetAllReplicaSets(d, dd) + oldRSs, _, newRS, err := deploymentutil.GetAllReplicaSets(d, dd.versionedClient) if err == nil { fmt.Fprintf(out, "OldReplicaSets:\t%s\n", printReplicaSetsByLabels(oldRSs)) - var newRSs []*extensions.ReplicaSet + var newRSs []*versionedextension.ReplicaSet if newRS != nil { newRSs = append(newRSs, newRS) } @@ -2248,7 +2251,7 @@ func printReplicationControllersByLabels(matchingRCs []*api.ReplicationControlle return list } -func printReplicaSetsByLabels(matchingRSs []*extensions.ReplicaSet) string { +func printReplicaSetsByLabels(matchingRSs []*versionedextension.ReplicaSet) string { // Format the matching ReplicaSets into strings. rsStrings := make([]string, 0, len(matchingRSs)) for _, rs := range matchingRSs { diff --git a/pkg/kubectl/describe_test.go b/pkg/kubectl/describe_test.go index 9d7cca87d3..5ab645fdb3 100644 --- a/pkg/kubectl/describe_test.go +++ b/pkg/kubectl/describe_test.go @@ -30,11 +30,14 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" + "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" + versionedfake "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/fake" "k8s.io/kubernetes/pkg/util/intstr" ) @@ -618,16 +621,18 @@ func TestPersistentVolumeDescriber(t *testing.T) { } func TestDescribeDeployment(t *testing.T) { - fake := fake.NewSimpleClientset(&extensions.Deployment{ - ObjectMeta: api.ObjectMeta{ + fake := fake.NewSimpleClientset() + versionedFake := versionedfake.NewSimpleClientset(&v1beta1.Deployment{ + ObjectMeta: v1.ObjectMeta{ Name: "bar", Namespace: "foo", }, - Spec: extensions.DeploymentSpec{ - Template: api.PodTemplateSpec{}, + Spec: v1beta1.DeploymentSpec{ + Selector: &unversioned.LabelSelector{}, + Template: v1.PodTemplateSpec{}, }, }) - d := DeploymentDescriber{fake} + d := DeploymentDescriber{fake, versionedFake} out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) if err != nil { t.Errorf("unexpected error: %v", err) @@ -748,12 +753,16 @@ func TestDescribeEvents(t *testing.T) { }, events), }, "DeploymentDescriber": &DeploymentDescriber{ - fake.NewSimpleClientset(&extensions.Deployment{ - ObjectMeta: api.ObjectMeta{ + fake.NewSimpleClientset(events), + versionedfake.NewSimpleClientset(&v1beta1.Deployment{ + ObjectMeta: v1.ObjectMeta{ Name: "bar", Namespace: "foo", }, - }, events), + Spec: v1beta1.DeploymentSpec{ + Selector: &unversioned.LabelSelector{}, + }, + }), }, "EndpointsDescriber": &EndpointsDescriber{ fake.NewSimpleClientset(&api.Endpoints{ diff --git a/pkg/kubectl/history.go b/pkg/kubectl/history.go index 8485139fe2..a6522d4916 100644 --- a/pkg/kubectl/history.go +++ b/pkg/kubectl/history.go @@ -24,6 +24,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" @@ -54,11 +55,12 @@ type DeploymentHistoryViewer struct { // ViewHistory returns a revision-to-replicaset map as the revision history of a deployment func (h *DeploymentHistoryViewer) ViewHistory(namespace, name string, revision int64) (string, error) { - deployment, err := h.c.Extensions().Deployments(namespace).Get(name) + versionedClient := versionedClientsetForDeployment(h.c) + deployment, err := versionedClient.Extensions().Deployments(namespace).Get(name) if err != nil { return "", fmt.Errorf("failed to retrieve deployment %s: %v", name, err) } - _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, h.c) + _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, versionedClient) if err != nil { return "", fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", name, err) } @@ -67,7 +69,7 @@ func (h *DeploymentHistoryViewer) ViewHistory(namespace, name string, revision i allRSs = append(allRSs, newRS) } - historyInfo := make(map[int64]*api.PodTemplateSpec) + historyInfo := make(map[int64]*v1.PodTemplateSpec) for _, rs := range allRSs { v, err := deploymentutil.Revision(rs) if err != nil { @@ -94,7 +96,11 @@ func (h *DeploymentHistoryViewer) ViewHistory(namespace, name string, revision i return "", fmt.Errorf("unable to find the specified revision") } buf := bytes.NewBuffer([]byte{}) - DescribePodTemplate(template, buf) + internalTemplate := &api.PodTemplateSpec{} + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(template, internalTemplate, nil); err != nil { + return "", fmt.Errorf("failed to convert podtemplate, %v", err) + } + DescribePodTemplate(internalTemplate, buf) return buf.String(), nil } diff --git a/pkg/kubectl/rollback.go b/pkg/kubectl/rollback.go index eb59575888..9b1ddc0057 100644 --- a/pkg/kubectl/rollback.go +++ b/pkg/kubectl/rollback.go @@ -25,7 +25,9 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" + externalextensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util" "k8s.io/kubernetes/pkg/runtime" @@ -130,7 +132,12 @@ func isRollbackEvent(e *api.Event) (bool, string) { } func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRevision int64) (string, error) { - _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(deployment, c) + externalDeployment := &externalextensions.Deployment{} + if err := api.Scheme.Convert(deployment, externalDeployment, nil); err != nil { + return "", fmt.Errorf("failed to convert deployment, %v", err) + } + versionedClient := versionedClientsetForDeployment(c) + _, allOldRSs, newRS, err := deploymentutil.GetAllReplicaSets(externalDeployment, versionedClient) if err != nil { return "", fmt.Errorf("failed to retrieve replica sets from deployment %s: %v", deployment.Name, err) } @@ -139,7 +146,7 @@ func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRe allRSs = append(allRSs, newRS) } - revisionToSpec := make(map[int64]*api.PodTemplateSpec) + revisionToSpec := make(map[int64]*v1.PodTemplateSpec) for _, rs := range allRSs { v, err := deploymentutil.Revision(rs) if err != nil { @@ -158,7 +165,11 @@ func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRe return "", fmt.Errorf("unable to find specified revision") } buf := bytes.NewBuffer([]byte{}) - DescribePodTemplate(template, buf) + internalTemplate := &api.PodTemplateSpec{} + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(template, internalTemplate, nil); err != nil { + return "", fmt.Errorf("failed to convert podtemplate, %v", err) + } + DescribePodTemplate(internalTemplate, buf) return buf.String(), nil } @@ -172,6 +183,10 @@ func simpleDryRun(deployment *extensions.Deployment, c clientset.Interface, toRe template, _ := revisionToSpec[revisions[len(revisions)-1]] buf := bytes.NewBuffer([]byte{}) buf.WriteString("\n") - DescribePodTemplate(template, buf) + internalTemplate := &api.PodTemplateSpec{} + if err := v1.Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(template, internalTemplate, nil); err != nil { + return "", fmt.Errorf("failed to convert podtemplate, %v", err) + } + DescribePodTemplate(internalTemplate, buf) return buf.String(), nil } diff --git a/pkg/kubectl/rolling_updater.go b/pkg/kubectl/rolling_updater.go index 76c14d976f..67b60e2896 100644 --- a/pkg/kubectl/rolling_updater.go +++ b/pkg/kubectl/rolling_updater.go @@ -27,6 +27,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/unversioned" + "k8s.io/kubernetes/pkg/api/v1" coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion" "k8s.io/kubernetes/pkg/client/retry" client "k8s.io/kubernetes/pkg/client/unversioned" @@ -420,7 +421,11 @@ func (r *RollingUpdater) readyPods(oldRc, newRc *api.ReplicationController, minR return 0, 0, err } for _, pod := range pods.Items { - if !deploymentutil.IsPodAvailable(&pod, minReadySeconds, r.nowFn().Time) { + v1Pod := &v1.Pod{} + if err := v1.Convert_api_Pod_To_v1_Pod(&pod, v1Pod, nil); err != nil { + return 0, 0, err + } + if !deploymentutil.IsPodAvailable(v1Pod, minReadySeconds, r.nowFn().Time) { continue } switch controller.Name { diff --git a/pkg/kubectl/rollout_status.go b/pkg/kubectl/rollout_status.go index 0fbeffaee5..7f2404b5f7 100644 --- a/pkg/kubectl/rollout_status.go +++ b/pkg/kubectl/rollout_status.go @@ -59,7 +59,7 @@ func (s *DeploymentStatusViewer) Status(namespace, name string, revision int64) } } if deployment.Generation <= deployment.Status.ObservedGeneration { - cond := util.GetDeploymentCondition(deployment.Status, extensions.DeploymentProgressing) + cond := util.GetDeploymentConditionInternal(deployment.Status, extensions.DeploymentProgressing) if cond != nil && cond.Reason == util.TimedOutReason { return "", false, fmt.Errorf("deployment %q exceeded its progress deadline", name) } diff --git a/pkg/kubectl/sorted_resource_name_list.go b/pkg/kubectl/sorted_resource_name_list.go index aad1d80747..f5f44c86bd 100644 --- a/pkg/kubectl/sorted_resource_name_list.go +++ b/pkg/kubectl/sorted_resource_name_list.go @@ -79,7 +79,7 @@ func (list SortableVolumeMounts) Less(i, j int) bool { func SortedQoSResourceNames(list qos.QOSList) []api.ResourceName { resources := make([]api.ResourceName, 0, len(list)) for res := range list { - resources = append(resources, res) + resources = append(resources, api.ResourceName(res)) } sort.Sort(SortableResourceNames(resources)) return resources diff --git a/pkg/kubectl/stop.go b/pkg/kubectl/stop.go index deb273b7c8..11def8c030 100644 --- a/pkg/kubectl/stop.go +++ b/pkg/kubectl/stop.go @@ -429,7 +429,7 @@ func (reaper *DeploymentReaper) Stop(namespace, name string, timeout time.Durati } // Use observedGeneration to determine if the deployment controller noticed the pause. - if err := deploymentutil.WaitForObservedDeployment(func() (*extensions.Deployment, error) { + if err := deploymentutil.WaitForObservedDeploymentInternal(func() (*extensions.Deployment, error) { return deployments.Get(name) }, deployment.Generation, 1*time.Second, 1*time.Minute); err != nil { return err diff --git a/pkg/kubectl/stop_test.go b/pkg/kubectl/stop_test.go index 54c62a148b..a63090b743 100644 --- a/pkg/kubectl/stop_test.go +++ b/pkg/kubectl/stop_test.go @@ -438,7 +438,7 @@ func TestDeploymentStop(t *testing.T) { Replicas: 0, }, } - template := deploymentutil.GetNewReplicaSetTemplate(&deployment) + template := deploymentutil.GetNewReplicaSetTemplateInternal(&deployment) tests := []struct { Name string Objs []runtime.Object @@ -675,7 +675,7 @@ func TestDeploymentNotFoundError(t *testing.T) { Replicas: 0, }, } - template := deploymentutil.GetNewReplicaSetTemplate(deployment) + template := deploymentutil.GetNewReplicaSetTemplateInternal(deployment) fake := fake.NewSimpleClientset( deployment, diff --git a/pkg/kubectl/versioned_client.go b/pkg/kubectl/versioned_client.go new file mode 100644 index 0000000000..f0c82d6c3c --- /dev/null +++ b/pkg/kubectl/versioned_client.go @@ -0,0 +1,34 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kubectl + +import ( + internalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" + externalclientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" + core "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/core/v1" + extensions "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/extensions/v1beta1" +) + +func versionedClientsetForDeployment(internalClient internalclientset.Interface) externalclientset.Interface { + if internalClient == nil { + return &externalclientset.Clientset{} + } + return &externalclientset.Clientset{ + CoreV1Client: core.New(internalClient.Core().RESTClient()), + ExtensionsV1beta1Client: extensions.New(internalClient.Extensions().RESTClient()), + } +}