From 8af4ccb1110f2fa548df3098c87638e376a9b2ef Mon Sep 17 00:00:00 2001 From: markturansky Date: Thu, 13 Nov 2014 10:52:13 -0500 Subject: [PATCH] v1beta3 Pod refactor --- cmd/e2e/e2e.go | 6 +- cmd/integration/integration.go | 21 ++- pkg/api/conversion.go | 2 +- pkg/api/testapi/testapi.go | 10 ++ pkg/api/types.go | 30 +++- pkg/api/v1beta1/conversion.go | 57 +++++-- pkg/api/v1beta2/conversion.go | 55 +++++-- pkg/api/validation/validation.go | 16 +- pkg/api/validation/validation_test.go | 134 ++++++---------- pkg/client/client_test.go | 20 +-- pkg/controller/replication_controller.go | 6 +- pkg/controller/replication_controller_test.go | 4 +- pkg/kubecfg/parse_test.go | 15 +- pkg/kubecfg/resource_printer.go | 8 +- pkg/kubectl/cmd/log.go | 2 +- pkg/kubectl/describe.go | 8 +- pkg/kubectl/resource_printer.go | 6 +- pkg/master/pod_cache.go | 4 +- pkg/master/pod_cache_test.go | 2 +- pkg/registry/etcd/etcd.go | 46 +++--- pkg/registry/etcd/etcd_test.go | 133 ++++++++-------- pkg/registry/generic/etcd/etcd_test.go | 36 ++--- pkg/registry/pod/bound_pod_factory_test.go | 37 ++--- pkg/registry/pod/rest.go | 50 +++--- pkg/registry/pod/rest_test.go | 150 +++++++----------- pkg/scheduler/predicates.go | 18 +-- pkg/scheduler/predicates_test.go | 66 ++++---- pkg/scheduler/priorities.go | 2 +- pkg/scheduler/priorities_test.go | 43 +++-- pkg/scheduler/scheduler_test.go | 12 +- pkg/scheduler/spreading.go | 2 +- pkg/scheduler/spreading_test.go | 26 +-- pkg/service/endpoints_controller.go | 17 +- pkg/service/endpoints_controller_test.go | 78 ++++----- plugin/pkg/scheduler/factory/factory.go | 2 +- test/integration/client_test.go | 18 +-- 36 files changed, 569 insertions(+), 573 deletions(-) diff --git a/cmd/e2e/e2e.go b/cmd/e2e/e2e.go index 031997f77f139..d88ce542efa0c 100644 --- a/cmd/e2e/e2e.go +++ b/cmd/e2e/e2e.go @@ -46,10 +46,10 @@ func waitForPodRunning(c *client.Client, id string) { glog.Warningf("Get pod failed: %v", err) continue } - if pod.CurrentState.Status == api.PodRunning { + if pod.Status.Condition == api.PodRunning { break } - glog.Infof("Waiting for pod status to be running (%s)", pod.CurrentState.Status) + glog.Infof("Waiting for pod status to be running (%s)", pod.Status.Condition) } } @@ -153,7 +153,7 @@ func TestPodUpdate(c *client.Client) bool { value = "time" + value pod.Labels["time"] = value pod.ResourceVersion = podOut.ResourceVersion - pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID + pod.UID = podOut.UID pod, err = podClient.Update(pod) if err != nil { glog.Errorf("Failed to update pod: %v", err) diff --git a/cmd/integration/integration.go b/cmd/integration/integration.go index 65614dc054a5a..3825b26c79285 100644 --- a/cmd/integration/integration.go +++ b/cmd/integration/integration.go @@ -216,7 +216,7 @@ func podsOnMinions(c *client.Client, pods api.PodList) wait.ConditionFunc { podInfo := fakeKubeletClient{} return func() (bool, error) { for i := range pods.Items { - host, id, namespace := pods.Items[i].CurrentState.Host, pods.Items[i].Name, pods.Items[i].Namespace + host, id, namespace := pods.Items[i].Status.Host, pods.Items[i].Name, pods.Items[i].Namespace if len(host) == 0 { return false, nil } @@ -499,21 +499,18 @@ func runServiceTest(client *client.Client) { "name": "thisisalonglabel", }, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - Containers: []api.Container{ - { - Name: "c1", - Image: "foo", - Ports: []api.Port{ - {ContainerPort: 1234}, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "c1", + Image: "foo", + Ports: []api.Port{ + {ContainerPort: 1234}, }, }, }, }, - CurrentState: api.PodState{ + Status: api.PodStatus{ PodIP: "1.2.3.4", }, } diff --git a/pkg/api/conversion.go b/pkg/api/conversion.go index c679ef7c3ca16..98c3f85e84996 100644 --- a/pkg/api/conversion.go +++ b/pkg/api/conversion.go @@ -81,7 +81,7 @@ func init() { // Convert Pod to BoundPod func(in *Pod, out *BoundPod, s conversion.Scope) error { - if err := s.Convert(&in.DesiredState.Manifest, out, 0); err != nil { + if err := s.Convert(&in.Spec, &out.Spec, 0); err != nil { return err } // Only copy a subset of fields, and override manifest attributes with the pod diff --git a/pkg/api/testapi/testapi.go b/pkg/api/testapi/testapi.go index b75604222c545..bd7f6e1e42053 100644 --- a/pkg/api/testapi/testapi.go +++ b/pkg/api/testapi/testapi.go @@ -45,6 +45,16 @@ func Codec() runtime.Codec { return interfaces.Codec } +// Converter returns the api.Scheme for the API version to test against, as set by the +// KUBE_API_VERSION env var. +func Converter() runtime.ObjectConvertor { + interfaces, err := latest.InterfacesFor(Version()) + if err != nil { + panic(err) + } + return interfaces.ObjectConvertor +} + // MetadataAccessor returns the MetadataAccessor for the API version to test against, // as set by the KUBE_API_VERSION env var. func MetadataAccessor() meta.MetadataAccessor { diff --git a/pkg/api/types.go b/pkg/api/types.go index 19205e80b289b..71590f3145108 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -455,15 +455,37 @@ type PodSpec struct { NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` } +// PodStatus represents information about the status of a pod. Status may trail the actual +// state of a system. +type PodStatus struct { + Condition PodCondition `json:"condition,omitempty" yaml:"condition,omitempty"` + + // Host is the name of the node that this Pod is currently bound to, or empty if no + // assignment has been done. + Host string `json:"host,omitempty" yaml:"host,omitempty"` + HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"` + PodIP string `json:"podIP,omitempty" yaml:"podIP,omitempty"` + + // The key of this map is the *name* of the container within the manifest; it has one + // entry per container in the manifest. The value of this map is currently the output + // of `docker inspect`. This output format is *not* final and should not be relied + // upon. + // TODO: Make real decisions about what our info should look like. Re-enable fuzz test + // when we have done this. + Info PodInfo `json:"info,omitempty" yaml:"info,omitempty"` +} + // Pod is a collection of containers, used as either input (create, update) or as output (list, get). type Pod struct { TypeMeta `json:",inline" yaml:",inline"` ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` - DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` - CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"` - // NodeSelector is a selector which must be true for the pod to fit on a node - NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` + // Spec defines the behavior of a pod. + Spec PodSpec `json:"spec,omitempty" yaml:"spec,omitempty"` + + // Status represents the current information about a pod. This data may not be up + // to date. + Status PodStatus `json:"status,omitempty" yaml:"status,omitempty"` } // PodTemplateSpec describes the data a pod should have when created from a template diff --git a/pkg/api/v1beta1/conversion.go b/pkg/api/v1beta1/conversion.go index 3208f2957bead..3c143367068b8 100644 --- a/pkg/api/v1beta1/conversion.go +++ b/pkg/api/v1beta1/conversion.go @@ -160,6 +160,32 @@ func init() { return nil }, + func(in *newer.PodStatus, out *PodState, s conversion.Scope) error { + if err := s.Convert(&in.Condition, &out.Status, 0); err != nil { + return err + } + if err := s.Convert(&in.Info, &out.Info, 0); err != nil { + return err + } + out.Host = in.Host + out.HostIP = in.HostIP + out.PodIP = in.PodIP + return nil + }, + func(in *PodState, out *newer.PodStatus, s conversion.Scope) error { + if err := s.Convert(&in.Status, &out.Condition, 0); err != nil { + return err + } + if err := s.Convert(&in.Info, &out.Info, 0); err != nil { + return err + } + + out.Host = in.Host + out.HostIP = in.HostIP + out.PodIP = in.PodIP + return nil + }, + // Convert all to the new PodCondition constants func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error { switch *in { @@ -189,7 +215,7 @@ func init() { case PodRunning: *out = newer.PodRunning case PodTerminated: - // Older API versions did not contain enough info to map to PodFailed + // Older API versions did not contain enough info to map to PodSucceeded *out = newer.PodFailed default: return errors.New("The string provided is not a valid PodCondition constant value") @@ -208,15 +234,13 @@ func init() { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } - - if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil { + if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } - if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil { + if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil { return err } - - if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil { + if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } return nil @@ -231,15 +255,13 @@ func init() { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } - - if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil { + if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } - if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil { + if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil { return err } - - if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil { + if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } return nil @@ -326,6 +348,19 @@ func init() { return nil }, + func(in *newer.PodSpec, out *BoundPod, s conversion.Scope) error { + if err := s.Convert(&in, &out.Spec, 0); err != nil { + return err + } + return nil + }, + func(in *BoundPod, out *newer.PodSpec, s conversion.Scope) error { + if err := s.Convert(&in.Spec, &out, 0); err != nil { + return err + } + return nil + }, + func(in *newer.PodSpec, out *ContainerManifest, s conversion.Scope) error { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { return err diff --git a/pkg/api/v1beta2/conversion.go b/pkg/api/v1beta2/conversion.go index 9ae6e30e0791f..a11c35e2fb26d 100644 --- a/pkg/api/v1beta2/conversion.go +++ b/pkg/api/v1beta2/conversion.go @@ -119,7 +119,7 @@ func init() { case PodRunning: *out = newer.PodRunning case PodTerminated: - // Older API versions did not contain enough info to map to PodFailed + // Older API versions did not contain enough info to map to PodSucceeded *out = newer.PodFailed default: return errors.New("The string provided is not a valid PodCondition constant value") @@ -138,15 +138,13 @@ func init() { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } - - if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil { + if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil { return err } - if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil { + if err := s.Convert(&in.Status, &out.CurrentState, 0); err != nil { return err } - - if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil { + if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil { return err } return nil @@ -161,15 +159,13 @@ func init() { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { return err } - - if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil { + if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil { return err } - if err := s.Convert(&in.CurrentState, &out.CurrentState, 0); err != nil { + if err := s.Convert(&in.CurrentState, &out.Status, 0); err != nil { return err } - - if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil { + if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil { return err } return nil @@ -282,6 +278,43 @@ func init() { return nil }, + func(in *newer.PodStatus, out *PodState, s conversion.Scope) error { + if err := s.Convert(&in.Condition, &out.Status, 0); err != nil { + return err + } + if err := s.Convert(&in.Info, &out.Info, 0); err != nil { + return err + } + out.Host = in.Host + out.HostIP = in.HostIP + out.PodIP = in.PodIP + return nil + }, + func(in *PodState, out *newer.PodStatus, s conversion.Scope) error { + if err := s.Convert(&in.Status, &out.Condition, 0); err != nil { + return err + } + if err := s.Convert(&in.Info, &out.Info, 0); err != nil { + return err + } + out.Host = in.Host + out.HostIP = in.HostIP + out.PodIP = in.PodIP + return nil + }, + + func(in *newer.PodSpec, out *PodState, s conversion.Scope) error { + if err := s.Convert(&in, &out.Manifest, 0); err != nil { + return err + } + return nil + }, + func(in *PodState, out *newer.PodSpec, s conversion.Scope) error { + if err := s.Convert(&in.Manifest, &out, 0); err != nil { + return err + } + return nil + }, func(in *newer.Service, out *Service, s conversion.Scope) error { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { return err diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 87c86cf3c3241..13358066f5d6b 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -345,7 +345,7 @@ func ValidatePod(pod *api.Pod) errs.ValidationErrorList { if !util.IsDNSSubdomain(pod.Namespace) { allErrs = append(allErrs, errs.NewFieldInvalid("namespace", pod.Namespace)) } - allErrs = append(allErrs, ValidatePodState(&pod.DesiredState).Prefix("desiredState")...) + allErrs = append(allErrs, ValidatePodSpec(&pod.Spec).Prefix("spec")...) allErrs = append(allErrs, validateLabels(pod.Labels)...) return allErrs } @@ -383,8 +383,8 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { allErrs = append(allErrs, errs.NewFieldInvalid("name", newPod.Name)) } - if len(newPod.DesiredState.Manifest.Containers) != len(oldPod.DesiredState.Manifest.Containers) { - allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers)) + if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) { + allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers)) return allErrs } pod := *newPod @@ -392,13 +392,13 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList { pod.ResourceVersion = oldPod.ResourceVersion // Tricky, we need to copy the container list so that we don't overwrite the update var newContainers []api.Container - for ix, container := range pod.DesiredState.Manifest.Containers { - container.Image = oldPod.DesiredState.Manifest.Containers[ix].Image + for ix, container := range pod.Spec.Containers { + container.Image = oldPod.Spec.Containers[ix].Image newContainers = append(newContainers, container) } - pod.DesiredState.Manifest.Containers = newContainers - if !reflect.DeepEqual(pod.DesiredState.Manifest, oldPod.DesiredState.Manifest) { - allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers)) + pod.Spec.Containers = newContainers + if !reflect.DeepEqual(pod.Spec, oldPod.Spec) { + allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers)) } return allErrs } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 31cc120a0b9e7..6e92c37dcb5c5 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -374,13 +374,9 @@ func TestValidatePod(t *testing.T) { "foo": "bar", }, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - ID: "abc", - RestartPolicy: api.RestartPolicy{ - Always: &api.RestartPolicyAlways{}, - }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicy{ + Always: &api.RestartPolicyAlways{}, }, }, }) @@ -395,28 +391,16 @@ func TestValidatePod(t *testing.T) { "foo": "bar", }, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"}, - }, + Spec: api.PodSpec{}, }) if len(errs) != 0 { t.Errorf("Unexpected non-zero error list: %#v", errs) } - errs = ValidatePod(&api.Pod{ - ObjectMeta: api.ObjectMeta{ - Name: "foo", Namespace: api.NamespaceDefault, - Labels: map[string]string{ - "foo": "bar", - }, - }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - ID: "abc", - RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{}, - Never: &api.RestartPolicyNever{}}, - }, + errs = ValidatePodSpec(&api.PodSpec{ + RestartPolicy: api.RestartPolicy{ + Always: &api.RestartPolicyAlways{}, + Never: &api.RestartPolicyNever{}, }, }) if len(errs) != 1 { @@ -436,9 +420,7 @@ func TestValidatePod(t *testing.T) { "rfc952-24chars-orless": "bar", //good label }, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"}, - }, + Spec: api.PodSpec{}, }) if len(errs) != 5 { t.Errorf("Unexpected non-zero error list: %#v", errs) @@ -488,27 +470,23 @@ func TestValidatePodUpdate(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V1", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V1", }, }, }, }, api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V2", - }, - { - Image: "bar:V2", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V2", + }, + { + Image: "bar:V2", }, }, }, @@ -519,24 +497,20 @@ func TestValidatePodUpdate(t *testing.T) { { api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V1", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V1", }, }, }, }, api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V2", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V2", }, }, }, @@ -547,26 +521,22 @@ func TestValidatePodUpdate(t *testing.T) { { api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V1", - CPU: 100, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V1", + CPU: 100, }, }, }, }, api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V2", - CPU: 1000, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V2", + CPU: 1000, }, }, }, @@ -577,14 +547,12 @@ func TestValidatePodUpdate(t *testing.T) { { api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V1", - Ports: []api.Port{ - {HostPort: 8080, ContainerPort: 80}, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V1", + Ports: []api.Port{ + {HostPort: 8080, ContainerPort: 80}, }, }, }, @@ -592,14 +560,12 @@ func TestValidatePodUpdate(t *testing.T) { }, api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Image: "foo:V2", - Ports: []api.Port{ - {HostPort: 8000, ContainerPort: 80}, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:V2", + Ports: []api.Port{ + {HostPort: 8000, ContainerPort: 80}, }, }, }, diff --git a/pkg/client/client_test.go b/pkg/client/client_test.go index 11d3b3a451ed8..8cf2bcc29bf0f 100644 --- a/pkg/client/client_test.go +++ b/pkg/client/client_test.go @@ -172,8 +172,8 @@ func TestListPods(t *testing.T) { Body: &api.PodList{ Items: []api.Pod{ { - CurrentState: api.PodState{ - Status: api.PodRunning, + Status: api.PodStatus{ + Condition: api.PodRunning, }, ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ @@ -205,8 +205,8 @@ func TestListPodsLabels(t *testing.T) { Body: &api.PodList{ Items: []api.Pod{ { - CurrentState: api.PodState{ - Status: api.PodRunning, + Status: api.PodStatus{ + Condition: api.PodRunning, }, ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ @@ -233,8 +233,8 @@ func TestGetPod(t *testing.T) { Response: Response{ StatusCode: 200, Body: &api.Pod{ - CurrentState: api.PodState{ - Status: api.PodRunning, + Status: api.PodStatus{ + Condition: api.PodRunning, }, ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ @@ -260,8 +260,8 @@ func TestDeletePod(t *testing.T) { func TestCreatePod(t *testing.T) { requestPod := &api.Pod{ - CurrentState: api.PodState{ - Status: api.PodRunning, + Status: api.PodStatus{ + Condition: api.PodRunning, }, ObjectMeta: api.ObjectMeta{ Labels: map[string]string{ @@ -291,8 +291,8 @@ func TestUpdatePod(t *testing.T) { "name": "baz", }, }, - CurrentState: api.PodState{ - Status: api.PodRunning, + Status: api.PodStatus{ + Condition: api.PodRunning, }, } c := &testClient{ diff --git a/pkg/controller/replication_controller.go b/pkg/controller/replication_controller.go index 32125d5e8aee8..666d3ac3dd2d6 100644 --- a/pkg/controller/replication_controller.go +++ b/pkg/controller/replication_controller.go @@ -62,7 +62,7 @@ func (r RealPodControl) createReplica(namespace string, controller api.Replicati Labels: desiredLabels, }, } - if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.DesiredState.Manifest); err != nil { + if err := api.Scheme.Convert(&controller.Spec.Template.Spec, &pod.Spec); err != nil { glog.Errorf("Unable to convert pod template: %v", err) return } @@ -143,8 +143,8 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) { func (rm *ReplicationManager) filterActivePods(pods []api.Pod) []api.Pod { var result []api.Pod for _, value := range pods { - if api.PodSucceeded != value.CurrentState.Status && - api.PodFailed != value.CurrentState.Status { + if api.PodSucceeded != value.Status.Condition && + api.PodFailed != value.Status.Condition { result = append(result, value) } } diff --git a/pkg/controller/replication_controller_test.go b/pkg/controller/replication_controller_test.go index 4c728510cb64e..4a41bf9395215 100644 --- a/pkg/controller/replication_controller_test.go +++ b/pkg/controller/replication_controller_test.go @@ -219,9 +219,7 @@ func TestCreateReplica(t *testing.T) { ObjectMeta: api.ObjectMeta{ Labels: controllerSpec.Spec.Template.Labels, }, - DesiredState: api.PodState{ - Manifest: manifest, - }, + Spec: controllerSpec.Spec.Template.Spec, } fakeHandler.ValidateRequest(t, makeURL("/pods?namespace=default"), "POST", nil) actualPod, err := client.Codec.Decode([]byte(fakeHandler.RequestBody)) diff --git a/pkg/kubecfg/parse_test.go b/pkg/kubecfg/parse_test.go index 619518770f8bf..d9a53fb981851 100644 --- a/pkg/kubecfg/parse_test.go +++ b/pkg/kubecfg/parse_test.go @@ -71,15 +71,12 @@ func TestParsePod(t *testing.T) { DoParseTest(t, "pods", &api.Pod{ TypeMeta: api.TypeMeta{APIVersion: "v1beta1", Kind: "Pod"}, ObjectMeta: api.ObjectMeta{Name: "test pod"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - ID: "My manifest", - Containers: []api.Container{ - {Name: "my container"}, - }, - Volumes: []api.Volume{ - {Name: "volume"}, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + {Name: "my container"}, + }, + Volumes: []api.Volume{ + {Name: "volume"}, }, }, }, v1beta1.Codec, testParser) diff --git a/pkg/kubecfg/resource_printer.go b/pkg/kubecfg/resource_printer.go index 7c540aa06717a..4b3ce61b7ef5f 100644 --- a/pkg/kubecfg/resource_printer.go +++ b/pkg/kubecfg/resource_printer.go @@ -177,7 +177,7 @@ func (h *HumanReadablePrinter) printHeader(columnNames []string, w io.Writer) er return err } -func makeImageList(manifest api.ContainerManifest) string { +func makeImageList(manifest api.PodSpec) string { var images []string for _, container := range manifest.Containers { images = append(images, container.Image) @@ -202,9 +202,9 @@ func podHostString(host, ip string) string { func printPod(pod *api.Pod, w io.Writer) error { _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", - pod.Name, makeImageList(pod.DesiredState.Manifest), - podHostString(pod.CurrentState.Host, pod.CurrentState.HostIP), - labels.Set(pod.Labels), pod.CurrentState.Status) + pod.Name, makeImageList(pod.Spec), + podHostString(pod.Status.Host, pod.Status.HostIP), + labels.Set(pod.Labels), pod.Status.Condition) return err } diff --git a/pkg/kubectl/cmd/log.go b/pkg/kubectl/cmd/log.go index 1aee8f86e8ab5..7dc54fb3a4f1e 100644 --- a/pkg/kubectl/cmd/log.go +++ b/pkg/kubectl/cmd/log.go @@ -35,7 +35,7 @@ func NewCmdLog(out io.Writer) *cobra.Command { data, err := client.RESTClient.Get(). Path("proxy/minions"). - Path(pod.CurrentState.Host). + Path(pod.Status.Host). Path("containerLogs"). Path(getKubeNamespace(cmd)). Path(args[0]). diff --git a/pkg/kubectl/describe.go b/pkg/kubectl/describe.go index dec398aac3177..59b57085c3c82 100644 --- a/pkg/kubectl/describe.go +++ b/pkg/kubectl/describe.go @@ -82,7 +82,7 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) { // TODO: remove me when pods are converted spec := &api.PodSpec{} - if err := api.Scheme.Convert(&pod.DesiredState.Manifest, spec); err != nil { + if err := api.Scheme.Convert(&pod.Spec, spec); err != nil { glog.Errorf("Unable to convert pod manifest: %v", err) } @@ -91,9 +91,9 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) { return tabbedString(func(out io.Writer) error { fmt.Fprintf(out, "Name:\t%s\n", pod.Name) fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(spec)) - fmt.Fprintf(out, "Host:\t%s\n", pod.CurrentState.Host+"/"+pod.CurrentState.HostIP) + fmt.Fprintf(out, "Host:\t%s\n", pod.Status.Host+"/"+pod.Status.HostIP) fmt.Fprintf(out, "Labels:\t%s\n", formatLabels(pod.Labels)) - fmt.Fprintf(out, "Status:\t%s\n", string(pod.CurrentState.Status)) + fmt.Fprintf(out, "Status:\t%s\n", string(pod.Status.Condition)) fmt.Fprintf(out, "Replication Controllers:\t%s\n", getReplicationControllersForLabels(rc, labels.Set(pod.Labels))) if events != nil { describeEvents(events, out) @@ -247,7 +247,7 @@ func getPodStatusForReplicationController(c client.PodInterface, controller *api return } for _, pod := range rcPods.Items { - switch pod.CurrentState.Status { + switch pod.Status.Condition { case api.PodRunning: running++ case api.PodPending: diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index 3f517fa33d0b9..46257eb7eb293 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -257,7 +257,7 @@ func podHostString(host, ip string) string { func printPod(pod *api.Pod, w io.Writer) error { // TODO: remove me when pods are converted spec := &api.PodSpec{} - if err := api.Scheme.Convert(&pod.DesiredState.Manifest, spec); err != nil { + if err := api.Scheme.Convert(&pod.Spec, spec); err != nil { glog.Errorf("Unable to convert pod manifest: %v", err) } il := listOfImages(spec) @@ -268,8 +268,8 @@ func printPod(pod *api.Pod, w io.Writer) error { } _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", pod.Name, firstImage, - podHostString(pod.CurrentState.Host, pod.CurrentState.HostIP), - labels.Set(pod.Labels), pod.CurrentState.Status) + podHostString(pod.Status.Host, pod.Status.HostIP), + labels.Set(pod.Labels), pod.Status.Condition) if err != nil { return err } diff --git a/pkg/master/pod_cache.go b/pkg/master/pod_cache.go index 36a7616d44b3a..b9ee60e062ae4 100644 --- a/pkg/master/pod_cache.go +++ b/pkg/master/pod_cache.go @@ -84,10 +84,10 @@ func (p *PodCache) UpdateAllContainers() { return } for _, pod := range pods.Items { - if pod.CurrentState.Host == "" { + if pod.Status.Host == "" { continue } - err := p.updatePodInfo(pod.CurrentState.Host, pod.Namespace, pod.Name) + err := p.updatePodInfo(pod.Status.Host, pod.Namespace, pod.Name) if err != nil && err != client.ErrPodInfoNotAvailable { glog.Errorf("Error synchronizing container: %v", err) } diff --git a/pkg/master/pod_cache_test.go b/pkg/master/pod_cache_test.go index 82170b7c120e3..a9c5ebd1b5f37 100644 --- a/pkg/master/pod_cache_test.go +++ b/pkg/master/pod_cache_test.go @@ -125,7 +125,7 @@ func TestPodGetPodInfoGetter(t *testing.T) { func TestPodUpdateAllContainers(t *testing.T) { pod := api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, - CurrentState: api.PodState{ + Status: api.PodStatus{ Host: "machine", }, } diff --git a/pkg/registry/etcd/etcd.go b/pkg/registry/etcd/etcd.go index ef07d648b85c0..da23454ac1f21 100644 --- a/pkg/registry/etcd/etcd.go +++ b/pkg/registry/etcd/etcd.go @@ -114,10 +114,6 @@ func (r *Registry) ListPodsPredicate(ctx api.Context, filter func(*api.Pod) bool filtered := []api.Pod{} for _, pod := range allPods.Items { if filter(&pod) { - // TODO: Currently nothing sets CurrentState.Host. We need a feedback loop that sets - // the CurrentState.Host and Status fields. Here we pretend that reality perfectly - // matches our desires. - pod.CurrentState.Host = pod.DesiredState.Host filtered = append(filtered, pod) } } @@ -153,10 +149,6 @@ func (r *Registry) GetPod(ctx api.Context, id string) (*api.Pod, error) { if err = r.ExtractObj(key, &pod, false); err != nil { return nil, etcderr.InterpretGetError(err, "pod", id) } - // TODO: Currently nothing sets CurrentState.Host. We need a feedback loop that sets - // the CurrentState.Host and Status fields. Here we pretend that reality perfectly - // matches our desires. - pod.CurrentState.Host = pod.DesiredState.Host return &pod, nil } @@ -167,11 +159,8 @@ func makeContainerKey(machine string) string { // CreatePod creates a pod based on a specification. func (r *Registry) CreatePod(ctx api.Context, pod *api.Pod) error { // Set current status to "Waiting". - pod.CurrentState.Status = api.PodPending - pod.CurrentState.Host = "" - // DesiredState.Host == "" is a signal to the scheduler that this pod needs scheduling. - pod.DesiredState.Status = api.PodRunning - pod.DesiredState.Host = "" + pod.Status.Condition = api.PodPending + pod.Status.Host = "" key, err := makePodKey(ctx, pod.Name) if err != nil { return err @@ -197,10 +186,10 @@ func (r *Registry) setPodHostTo(ctx api.Context, podID, oldMachine, machine stri if !ok { return nil, fmt.Errorf("unexpected object: %#v", obj) } - if pod.DesiredState.Host != oldMachine { - return nil, fmt.Errorf("pod %v is already assigned to host %v", pod.Name, pod.DesiredState.Host) + if pod.Status.Host != oldMachine { + return nil, fmt.Errorf("pod %v is already assigned to host %v", pod.Name, pod.Status.Host) } - pod.DesiredState.Host = machine + pod.Status.Host = machine finalPod = pod return pod, nil }) @@ -248,9 +237,9 @@ func (r *Registry) UpdatePod(ctx api.Context, pod *api.Pod) error { if err != nil { return err } - scheduled := podOut.DesiredState.Host != "" + scheduled := podOut.Status.Host != "" if scheduled { - pod.DesiredState.Host = podOut.DesiredState.Host + pod.Status.Host = podOut.Status.Host // If it's already been scheduled, limit the types of updates we'll accept. errs := validation.ValidatePodUpdate(pod, &podOut) if len(errs) != 0 { @@ -267,18 +256,19 @@ func (r *Registry) UpdatePod(ctx api.Context, pod *api.Pod) error { // never scheduled, just update. return nil } - containerKey := makeContainerKey(podOut.DesiredState.Host) - return r.AtomicUpdate(containerKey, &api.ContainerManifestList{}, func(in runtime.Object) (runtime.Object, error) { - manifests := in.(*api.ContainerManifestList) - for ix := range manifests.Items { - if manifests.Items[ix].ID == pod.Name { - manifests.Items[ix] = pod.DesiredState.Manifest - return manifests, nil + + containerKey := makeContainerKey(podOut.Status.Host) + return r.AtomicUpdate(containerKey, &api.BoundPods{}, func(in runtime.Object) (runtime.Object, error) { + boundPods := in.(*api.BoundPods) + for ix := range boundPods.Items { + if boundPods.Items[ix].Name == pod.Name { + boundPods.Items[ix].Spec = pod.Spec + return boundPods, nil } } // This really shouldn't happen - glog.Warningf("Couldn't find: %s in %#v", pod.Name, manifests) - return manifests, fmt.Errorf("Failed to update pod, couldn't find %s in %#v", pod.Name, manifests) + glog.Warningf("Couldn't find: %s in %#v", pod.Name, boundPods) + return boundPods, fmt.Errorf("Failed to update pod, couldn't find %s in %#v", pod.Name, boundPods) }) } @@ -299,7 +289,7 @@ func (r *Registry) DeletePod(ctx api.Context, podID string) error { if err != nil { return etcderr.InterpretDeleteError(err, "pod", podID) } - machine := pod.DesiredState.Host + machine := pod.Status.Host if machine == "" { // Pod was never scheduled anywhere, just return. return nil diff --git a/pkg/registry/etcd/etcd_test.go b/pkg/registry/etcd/etcd_test.go index a69a9bb5b5f71..18f52035502f8 100644 --- a/pkg/registry/etcd/etcd_test.go +++ b/pkg/registry/etcd/etcd_test.go @@ -131,12 +131,10 @@ func TestEtcdCreatePod(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Name: "foo", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -184,12 +182,10 @@ func TestEtcdCreatePodFailsWithoutNamespace(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Name: "foo", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -260,7 +256,7 @@ func TestEtcdCreatePodWithContainersError(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %v", err) } - if existingPod.DesiredState.Host == "machine" { + if existingPod.Status.Host == "machine" { t.Fatal("Pod's host changed in response to an non-apply-able binding.") } } @@ -287,13 +283,10 @@ func TestEtcdCreatePodWithContainersNotFound(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - ID: "foo", - Containers: []api.Container{ - { - Name: "foo", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -354,13 +347,10 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) { ObjectMeta: api.ObjectMeta{ Name: "foo", }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - ID: "foo", - Containers: []api.Container{ - { - Name: "foo", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -470,35 +460,38 @@ func TestEtcdUpdatePodScheduled(t *testing.T) { key, _ := makePodKey(ctx, "foo") fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{ - Host: "machine", - Manifest: api.ContainerManifest{ - ID: "foo", - Containers: []api.Container{ - { - Image: "foo:v1", - }, + Spec: api.PodSpec{ + // Host: "machine", + Containers: []api.Container{ + { + Image: "foo:v1", }, }, }, + Status: api.PodStatus{ + Host: "machine", + }, }), 1) contKey := "/registry/nodes/machine/boundpods" - fakeClient.Set(contKey, runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{ - Items: []api.ContainerManifest{ + fakeClient.Set(contKey, runtime.EncodeOrDie(latest.Codec, &api.BoundPods{ + Items: []api.BoundPod{ { - ID: "foo", - Containers: []api.Container{ - { - Image: "foo:v1", + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:v1", + }, }, }, - }, - { - ID: "bar", - Containers: []api.Container{ - { - Image: "bar:v1", + }, { + ObjectMeta: api.ObjectMeta{Name: "bar"}, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:v1", + }, }, }, }, @@ -514,16 +507,16 @@ func TestEtcdUpdatePodScheduled(t *testing.T) { "foo": "bar", }, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - ID: "foo", - Containers: []api.Container{ - { - Image: "foo:v2", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Image: "foo:v2", }, }, }, + Status: api.PodStatus{ + Host: "machine", + }, } err := registry.UpdatePod(ctx, &podIn) if err != nil { @@ -535,7 +528,6 @@ func TestEtcdUpdatePodScheduled(t *testing.T) { } var podOut api.Pod latest.Codec.DecodeInto([]byte(response.Node.Value), &podOut) - podIn.DesiredState.Host = "machine" if !reflect.DeepEqual(podOut, podIn) { t.Errorf("expected: %#v, got: %#v", podOut, podIn) } @@ -544,10 +536,13 @@ func TestEtcdUpdatePodScheduled(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %v", err) } - var list api.ContainerManifestList - latest.Codec.DecodeInto([]byte(response.Node.Value), &list) - if len(list.Items) != 2 || !reflect.DeepEqual(list.Items[0], podIn.DesiredState.Manifest) { - t.Errorf("unexpected container list: %d %v %v", len(list.Items), list.Items[0], podIn.DesiredState.Manifest) + var list api.BoundPods + if err := latest.Codec.DecodeInto([]byte(response.Node.Value), &list); err != nil { + t.Fatalf("unexpected error decoding response: %v", err) + } + + if len(list.Items) != 2 || !reflect.DeepEqual(list.Items[0].Spec, podIn.Spec) { + t.Errorf("unexpected container list: %d\n items[0] - %#v\n podin.spec - %#v\n", len(list.Items), list.Items[0].Spec, podIn.Spec) } } @@ -558,8 +553,8 @@ func TestEtcdDeletePod(t *testing.T) { key, _ := makePodKey(ctx, "foo") fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, }), 0) fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{ Items: []api.BoundPod{ @@ -594,8 +589,8 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) { fakeClient.TestIndex = true key, _ := makePodKey(ctx, "foo") fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, }), 0) fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{ Items: []api.BoundPod{ @@ -680,14 +675,14 @@ func TestEtcdListPods(t *testing.T) { Nodes: []*etcd.Node{ { Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, }), }, { Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "bar"}, + Status: api.PodStatus{Host: "machine"}, }), }, }, @@ -704,8 +699,8 @@ func TestEtcdListPods(t *testing.T) { if len(pods.Items) != 2 || pods.Items[0].Name != "foo" || pods.Items[1].Name != "bar" { t.Errorf("Unexpected pod list: %#v", pods) } - if pods.Items[0].CurrentState.Host != "machine" || - pods.Items[1].CurrentState.Host != "machine" { + if pods.Items[0].Status.Host != "machine" || + pods.Items[1].Status.Host != "machine" { t.Errorf("Failed to populate host name.") } } diff --git a/pkg/registry/generic/etcd/etcd_test.go b/pkg/registry/generic/etcd/etcd_test.go index dd76590263aeb..0cf216fb4e2da 100644 --- a/pkg/registry/generic/etcd/etcd_test.go +++ b/pkg/registry/generic/etcd/etcd_test.go @@ -72,12 +72,12 @@ func (EverythingMatcher) Matches(obj runtime.Object) (bool, error) { func TestEtcdList(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "bar"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "bar"}, + Status: api.PodStatus{Host: "machine"}, } normalListResp := &etcd.Response{ @@ -154,12 +154,12 @@ func TestEtcdList(t *testing.T) { func TestEtcdCreate(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine2"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine2"}, } nodeWithPodA := tools.EtcdResponseWithError{ @@ -217,12 +217,12 @@ func TestEtcdCreate(t *testing.T) { func TestEtcdUpdate(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo"}, + Status: api.PodStatus{Host: "machine"}, } podB := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - DesiredState: api.PodState{Host: "machine2"}, + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + Status: api.PodStatus{Host: "machine2"}, } nodeWithPodA := tools.EtcdResponseWithError{ @@ -292,8 +292,8 @@ func TestEtcdUpdate(t *testing.T) { func TestEtcdGet(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + Status: api.PodStatus{Host: "machine"}, } nodeWithPodA := tools.EtcdResponseWithError{ @@ -348,8 +348,8 @@ func TestEtcdGet(t *testing.T) { func TestEtcdDelete(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + Status: api.PodStatus{Host: "machine"}, } nodeWithPodA := tools.EtcdResponseWithError{ @@ -404,8 +404,8 @@ func TestEtcdDelete(t *testing.T) { func TestEtcdWatch(t *testing.T) { podA := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - DesiredState: api.PodState{Host: "machine"}, + ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, + Status: api.PodStatus{Host: "machine"}, } respWithPodA := &etcd.Response{ Node: &etcd.Node{ diff --git a/pkg/registry/pod/bound_pod_factory_test.go b/pkg/registry/pod/bound_pod_factory_test.go index 4ce66b1a66e4b..c0ec30008227a 100644 --- a/pkg/registry/pod/bound_pod_factory_test.go +++ b/pkg/registry/pod/bound_pod_factory_test.go @@ -33,12 +33,10 @@ func TestMakeBoundPodNoServices(t *testing.T) { pod, err := factory.MakeBoundPod("machine", &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foobar"}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Name: "foo", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -83,12 +81,11 @@ func TestMakeBoundPodServices(t *testing.T) { } pod, err := factory.MakeBoundPod("machine", &api.Pod{ - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Name: "foo", - }, + ObjectMeta: api.ObjectMeta{Name: "foobar"}, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "foo", }, }, }, @@ -161,15 +158,13 @@ func TestMakeBoundPodServicesExistingEnvVar(t *testing.T) { } pod, err := factory.MakeBoundPod("machine", &api.Pod{ - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Env: []api.EnvVar{ - { - Name: "foo", - Value: "bar", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Env: []api.EnvVar{ + { + Name: "foo", + Value: "bar", }, }, }, diff --git a/pkg/registry/pod/rest.go b/pkg/registry/pod/rest.go index 40d9e70fa0947..ac7a8630aa670 100644 --- a/pkg/registry/pod/rest.go +++ b/pkg/registry/pod/rest.go @@ -29,7 +29,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" - "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/golang/glog" @@ -92,17 +91,15 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !api.ValidNamespace(ctx, &pod.ObjectMeta) { return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context")) } - pod.DesiredState.Manifest.UUID = util.NewUUID().String() + api.FillObjectMetaSystemFields(ctx, &pod.ObjectMeta) if len(pod.Name) == 0 { - pod.Name = pod.DesiredState.Manifest.UUID + // TODO properly handle auto-generated names. + // See https://github.com/GoogleCloudPlatform/kubernetes/issues/148 170 & 1135 + pod.Name = pod.UID } - pod.DesiredState.Manifest.ID = pod.Name if errs := validation.ValidatePod(pod); len(errs) > 0 { return nil, errors.NewInvalid("pod", pod.Name, errs) } - - api.FillObjectMetaSystemFields(ctx, &pod.ObjectMeta) - return apiserver.MakeAsync(func() (runtime.Object, error) { if err := rs.registry.CreatePod(ctx, pod); err != nil { return nil, err @@ -131,19 +128,19 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) { if err != nil { return pod, err } - pod.CurrentState.Status = status + pod.Status.Condition = status } - if pod.CurrentState.Host != "" { - pod.CurrentState.HostIP = rs.getInstanceIP(pod.CurrentState.Host) + if pod.Status.Host != "" { + pod.Status.HostIP = rs.getInstanceIP(pod.Status.Host) } return pod, err } func (rs *REST) podToSelectableFields(pod *api.Pod) labels.Set { return labels.Set{ - "name": pod.Name, - "DesiredState.Status": string(pod.DesiredState.Status), - "DesiredState.Host": pod.DesiredState.Host, + "name": pod.Name, + "Status.Condition": string(pod.Status.Condition), + "Status.Host": pod.Status.Host, } } @@ -166,9 +163,9 @@ func (rs *REST) List(ctx api.Context, label, field labels.Selector) (runtime.Obj if err != nil { return pod, err } - pod.CurrentState.Status = status - if pod.CurrentState.Host != "" { - pod.CurrentState.HostIP = rs.getInstanceIP(pod.CurrentState.Host) + pod.Status.Condition = status + if pod.Status.Host != "" { + pod.Status.HostIP = rs.getInstanceIP(pod.Status.Host) } } } @@ -201,20 +198,19 @@ func (rs *REST) Update(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE } func (rs *REST) fillPodInfo(pod *api.Pod) { - pod.CurrentState.Host = pod.DesiredState.Host - if pod.CurrentState.Host == "" { + if pod.Status.Host == "" { return } // Get cached info for the list currently. // TODO: Optionally use fresh info if rs.podCache != nil { - info, err := rs.podCache.GetPodInfo(pod.CurrentState.Host, pod.Namespace, pod.Name) + info, err := rs.podCache.GetPodInfo(pod.Status.Host, pod.Namespace, pod.Name) if err != nil { if err != client.ErrPodInfoNotAvailable { glog.Errorf("Error getting container info from cache: %#v", err) } if rs.podInfoGetter != nil { - info, err = rs.podInfoGetter.GetPodInfo(pod.CurrentState.Host, pod.Namespace, pod.Name) + info, err = rs.podInfoGetter.GetPodInfo(pod.Status.Host, pod.Namespace, pod.Name) } if err != nil { if err != client.ErrPodInfoNotAvailable { @@ -223,11 +219,11 @@ func (rs *REST) fillPodInfo(pod *api.Pod) { return } } - pod.CurrentState.Info = info + pod.Status.Info = info netContainerInfo, ok := info["net"] if ok { if netContainerInfo.PodIP != "" { - pod.CurrentState.PodIP = netContainerInfo.PodIP + pod.Status.PodIP = netContainerInfo.PodIP } else { glog.Warningf("No network settings: %#v", netContainerInfo) } @@ -269,7 +265,7 @@ func getInstanceIPFromCloud(cloud cloudprovider.Interface, host string) string { } func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodCondition, error) { - if pod.CurrentState.Host == "" { + if pod.Status.Host == "" { return api.PodPending, nil } if minions != nil { @@ -280,7 +276,7 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodConditio } found := false for _, minion := range res.Items { - if minion.Name == pod.CurrentState.Host { + if minion.Name == pod.Status.Host { found = true break } @@ -291,14 +287,14 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodConditio } else { glog.Errorf("Unexpected missing minion interface, status may be in-accurate") } - if pod.CurrentState.Info == nil { + if pod.Status.Info == nil { return api.PodPending, nil } running := 0 stopped := 0 unknown := 0 - for _, container := range pod.DesiredState.Manifest.Containers { - if containerStatus, ok := pod.CurrentState.Info[container.Name]; ok { + for _, container := range pod.Spec.Containers { + if containerStatus, ok := pod.Status.Info[container.Name]; ok { if containerStatus.State.Running != nil { running++ } else if containerStatus.State.Termination != nil { diff --git a/pkg/registry/pod/rest_test.go b/pkg/registry/pod/rest_test.go index 8ce317213dcde..fdf434ba75218 100644 --- a/pkg/registry/pod/rest_test.go +++ b/pkg/registry/pod/rest_test.go @@ -28,7 +28,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/client" - "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" + fake_cloud "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider/fake" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" @@ -62,12 +62,7 @@ func TestCreatePodRegistryError(t *testing.T) { storage := REST{ registry: podRegistry, } - desiredState := api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - }, - } - pod := &api.Pod{DesiredState: desiredState} + pod := &api.Pod{} ctx := api.NewDefaultContext() ch, err := storage.Create(ctx, pod) if err != nil { @@ -82,12 +77,7 @@ func TestCreatePodSetsIds(t *testing.T) { storage := REST{ registry: podRegistry, } - desiredState := api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - }, - } - pod := &api.Pod{DesiredState: desiredState} + pod := &api.Pod{} ctx := api.NewDefaultContext() ch, err := storage.Create(ctx, pod) if err != nil { @@ -98,23 +88,18 @@ func TestCreatePodSetsIds(t *testing.T) { if len(podRegistry.Pod.Name) == 0 { t.Errorf("Expected pod ID to be set, Got %#v", pod) } - if podRegistry.Pod.DesiredState.Manifest.ID != podRegistry.Pod.Name { + if pod.Name != podRegistry.Pod.Name { t.Errorf("Expected manifest ID to be equal to pod ID, Got %#v", pod) } } -func TestCreatePodSetsUUIDs(t *testing.T) { +func TestCreatePodSetsUID(t *testing.T) { podRegistry := registrytest.NewPodRegistry(nil) podRegistry.Err = fmt.Errorf("test error") storage := REST{ registry: podRegistry, } - desiredState := api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - }, - } - pod := &api.Pod{DesiredState: desiredState} + pod := &api.Pod{} ctx := api.NewDefaultContext() ch, err := storage.Create(ctx, pod) if err != nil { @@ -122,8 +107,8 @@ func TestCreatePodSetsUUIDs(t *testing.T) { } expectApiStatusError(t, ch, podRegistry.Err.Error()) - if len(podRegistry.Pod.DesiredState.Manifest.UUID) == 0 { - t.Errorf("Expected pod UUID to be set, Got %#v", pod) + if len(podRegistry.Pod.UID) == 0 { + t.Errorf("Expected pod UID to be set, Got %#v", pod) } } @@ -216,11 +201,11 @@ func TestListPodListSelection(t *testing.T) { { ObjectMeta: api.ObjectMeta{Name: "foo"}, }, { - ObjectMeta: api.ObjectMeta{Name: "bar"}, - DesiredState: api.PodState{Host: "barhost"}, + ObjectMeta: api.ObjectMeta{Name: "bar"}, + Status: api.PodStatus{Host: "barhost"}, }, { - ObjectMeta: api.ObjectMeta{Name: "baz"}, - DesiredState: api.PodState{Status: "bazstatus"}, + ObjectMeta: api.ObjectMeta{Name: "baz"}, + Status: api.PodStatus{Condition: "bazstatus"}, }, { ObjectMeta: api.ObjectMeta{ Name: "qux", @@ -251,16 +236,16 @@ func TestListPodListSelection(t *testing.T) { label: "label=qux", expectedIDs: util.NewStringSet("qux"), }, { - field: "DesiredState.Status=bazstatus", + field: "Status.Condition=bazstatus", expectedIDs: util.NewStringSet("baz"), }, { - field: "DesiredState.Host=barhost", + field: "Status.Host=barhost", expectedIDs: util.NewStringSet("bar"), }, { - field: "DesiredState.Host=", + field: "Status.Host=", expectedIDs: util.NewStringSet("foo", "baz", "qux", "zot"), }, { - field: "DesiredState.Host!=", + field: "Status.Host!=", expectedIDs: util.NewStringSet("bar"), }, } @@ -342,7 +327,7 @@ func TestGetPod(t *testing.T) { func TestGetPodCloud(t *testing.T) { fakeCloud := &fake_cloud.FakeCloud{} podRegistry := registrytest.NewPodRegistry(nil) - podRegistry.Pod = &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}, CurrentState: api.PodState{Host: "machine"}} + podRegistry.Pod = &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}, Status: api.PodStatus{Host: "machine"}} clock := &fakeClock{t: time.Now()} @@ -393,16 +378,13 @@ func TestMakePodStatus(t *testing.T) { }, }, } - desiredState := api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - Containers: []api.Container{ - {Name: "containerA"}, - {Name: "containerB"}, - }, + desiredState := api.PodSpec{ + Containers: []api.Container{ + {Name: "containerA"}, + {Name: "containerB"}, }, } - currentState := api.PodState{ + currentState := api.PodStatus{ Host: "machine", } runningState := api.ContainerStatus{ @@ -421,11 +403,11 @@ func TestMakePodStatus(t *testing.T) { status api.PodCondition test string }{ - {&api.Pod{DesiredState: desiredState, CurrentState: currentState}, api.PodPending, "waiting"}, + {&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"}, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Host: "machine-2", }, }, @@ -434,8 +416,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": runningState, @@ -448,8 +430,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": runningState, @@ -462,8 +444,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": stoppedState, "containerB": stoppedState, @@ -476,8 +458,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": stoppedState, "containerB": stoppedState, @@ -490,8 +472,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": runningState, "containerB": stoppedState, @@ -504,8 +486,8 @@ func TestMakePodStatus(t *testing.T) { }, { &api.Pod{ - DesiredState: desiredState, - CurrentState: api.PodState{ + Spec: desiredState, + Status: api.PodStatus{ Info: map[string]api.ContainerStatus{ "containerA": runningState, }, @@ -533,25 +515,14 @@ func TestPodStorageValidatesCreate(t *testing.T) { registry: podRegistry, } ctx := api.NewDefaultContext() - pod := &api.Pod{} - c, err := storage.Create(ctx, pod) - if c != nil { - t.Errorf("Expected nil channel") - } - if !errors.IsInvalid(err) { - t.Errorf("Expected to get an invalid resource error, got %v", err) - } -} - -func TestPodStorageValidatesUpdate(t *testing.T) { - podRegistry := registrytest.NewPodRegistry(nil) - podRegistry.Err = fmt.Errorf("test error") - storage := REST{ - registry: podRegistry, + pod := &api.Pod{ + ObjectMeta: api.ObjectMeta{ + Labels: map[string]string{ + "invalid-label-to-cause-validation-failure": "bar", + }, + }, } - ctx := api.NewDefaultContext() - pod := &api.Pod{} - c, err := storage.Update(ctx, pod) + c, err := storage.Create(ctx, pod) if c != nil { t.Errorf("Expected nil channel") } @@ -564,7 +535,7 @@ func TestCreatePod(t *testing.T) { podRegistry := registrytest.NewPodRegistry(nil) podRegistry.Pod = &api.Pod{ ObjectMeta: api.ObjectMeta{Name: "foo"}, - CurrentState: api.PodState{ + Status: api.PodStatus{ Host: "machine", }, } @@ -572,15 +543,8 @@ func TestCreatePod(t *testing.T) { registry: podRegistry, podPollPeriod: time.Millisecond * 100, } - desiredState := api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta1", - }, - } - pod := &api.Pod{ - ObjectMeta: api.ObjectMeta{Name: "foo"}, - DesiredState: desiredState, - } + pod := &api.Pod{} + pod.Name = "foo" ctx := api.NewDefaultContext() channel, err := storage.Create(ctx, pod) if err != nil { @@ -625,13 +589,13 @@ func TestFillPodInfo(t *testing.T) { storage := REST{ podCache: &fakeGetter, } - pod := api.Pod{DesiredState: api.PodState{Host: "foo"}} + pod := api.Pod{Status: api.PodStatus{Host: "foo"}} storage.fillPodInfo(&pod) - if !reflect.DeepEqual(fakeGetter.info, pod.CurrentState.Info) { - t.Errorf("Expected: %#v, Got %#v", fakeGetter.info, pod.CurrentState.Info) + if !reflect.DeepEqual(fakeGetter.info, pod.Status.Info) { + t.Errorf("Expected: %#v, Got %#v", fakeGetter.info, pod.Status.Info) } - if pod.CurrentState.PodIP != expectedIP { - t.Errorf("Expected %s, Got %s", expectedIP, pod.CurrentState.PodIP) + if pod.Status.PodIP != expectedIP { + t.Errorf("Expected %s, Got %s", expectedIP, pod.Status.PodIP) } } @@ -647,13 +611,13 @@ func TestFillPodInfoNoData(t *testing.T) { storage := REST{ podCache: &fakeGetter, } - pod := api.Pod{DesiredState: api.PodState{Host: "foo"}} + pod := api.Pod{Status: api.PodStatus{Host: "foo"}} storage.fillPodInfo(&pod) - if !reflect.DeepEqual(fakeGetter.info, pod.CurrentState.Info) { - t.Errorf("Expected %#v, Got %#v", fakeGetter.info, pod.CurrentState.Info) + if !reflect.DeepEqual(fakeGetter.info, pod.Status.Info) { + t.Errorf("Expected %#v, Got %#v", fakeGetter.info, pod.Status.Info) } - if pod.CurrentState.PodIP != expectedIP { - t.Errorf("Expected %s, Got %s", expectedIP, pod.CurrentState.PodIP) + if pod.Status.PodIP != expectedIP { + t.Errorf("Expected %s, Got %s", expectedIP, pod.Status.PodIP) } } diff --git a/pkg/scheduler/predicates.go b/pkg/scheduler/predicates.go index c6bde8192ae89..b3138b192395f 100644 --- a/pkg/scheduler/predicates.go +++ b/pkg/scheduler/predicates.go @@ -57,7 +57,7 @@ func isVolumeConflict(volume api.Volume, pod *api.Pod) bool { } pdName := volume.Source.GCEPersistentDisk.PDName - manifest := &(pod.DesiredState.Manifest) + manifest := &(pod.Spec) for ix := range manifest.Volumes { if manifest.Volumes[ix].Source.GCEPersistentDisk != nil && manifest.Volumes[ix].Source.GCEPersistentDisk.PDName == pdName { @@ -73,7 +73,7 @@ func isVolumeConflict(volume api.Volume, pod *api.Pod) bool { // there. This is GCE specific for now. // TODO: migrate this into some per-volume specific code? func NoDiskConflict(pod api.Pod, existingPods []api.Pod, node string) (bool, error) { - manifest := &(pod.DesiredState.Manifest) + manifest := &(pod.Spec) for ix := range manifest.Volumes { for podIx := range existingPods { if isVolumeConflict(manifest.Volumes[ix], &existingPods[podIx]) { @@ -95,9 +95,9 @@ type resourceRequest struct { func getResourceRequest(pod *api.Pod) resourceRequest { result := resourceRequest{} - for ix := range pod.DesiredState.Manifest.Containers { - result.memory += pod.DesiredState.Manifest.Containers[ix].Memory - result.milliCPU += pod.DesiredState.Manifest.Containers[ix].CPU + for ix := range pod.Spec.Containers { + result.memory += pod.Spec.Containers[ix].Memory + result.milliCPU += pod.Spec.Containers[ix].CPU } return result } @@ -151,10 +151,10 @@ type NodeSelector struct { } func (n *NodeSelector) PodSelectorMatches(pod api.Pod, existingPods []api.Pod, node string) (bool, error) { - if len(pod.NodeSelector) == 0 { + if len(pod.Spec.NodeSelector) == 0 { return true, nil } - selector := labels.SelectorFromSet(pod.NodeSelector) + selector := labels.SelectorFromSet(pod.Spec.NodeSelector) minion, err := n.info.GetNodeInfo(node) if err != nil { return false, err @@ -179,7 +179,7 @@ func PodFitsPorts(pod api.Pod, existingPods []api.Pod, node string) (bool, error func getUsedPorts(pods ...api.Pod) map[int]bool { ports := make(map[int]bool) for _, pod := range pods { - for _, container := range pod.DesiredState.Manifest.Containers { + for _, container := range pod.Spec.Containers { for _, podPort := range container.Ports { ports[podPort.HostPort] = true } @@ -198,7 +198,7 @@ func MapPodsToMachines(lister PodLister) (map[string][]api.Pod, error) { return map[string][]api.Pod{}, err } for _, scheduledPod := range pods { - host := scheduledPod.DesiredState.Host + host := scheduledPod.Status.Host machineToPods[host] = append(machineToPods[host], scheduledPod) } return machineToPods, nil diff --git a/pkg/scheduler/predicates_test.go b/pkg/scheduler/predicates_test.go index 9c9e34f9ee072..b8e54f5b2d4fb 100644 --- a/pkg/scheduler/predicates_test.go +++ b/pkg/scheduler/predicates_test.go @@ -56,10 +56,8 @@ func newResourcePod(usage ...resourceRequest) api.Pod { }) } return api.Pod{ - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: containers, - }, + Spec: api.PodSpec{ + Containers: containers, }, } } @@ -220,27 +218,23 @@ func TestGetUsedPorts(t *testing.T) { } func TestDiskConflicts(t *testing.T) { - volState := api.PodState{ - Manifest: api.ContainerManifest{ - Volumes: []api.Volume{ - { - Source: &api.VolumeSource{ - GCEPersistentDisk: &api.GCEPersistentDisk{ - PDName: "foo", - }, + volState := api.PodSpec{ + Volumes: []api.Volume{ + { + Source: &api.VolumeSource{ + GCEPersistentDisk: &api.GCEPersistentDisk{ + PDName: "foo", }, }, }, }, } - volState2 := api.PodState{ - Manifest: api.ContainerManifest{ - Volumes: []api.Volume{ - { - Source: &api.VolumeSource{ - GCEPersistentDisk: &api.GCEPersistentDisk{ - PDName: "bar", - }, + volState2 := api.PodSpec{ + Volumes: []api.Volume{ + { + Source: &api.VolumeSource{ + GCEPersistentDisk: &api.GCEPersistentDisk{ + PDName: "bar", }, }, }, @@ -253,9 +247,9 @@ func TestDiskConflicts(t *testing.T) { test string }{ {api.Pod{}, []api.Pod{}, true, "nothing"}, - {api.Pod{}, []api.Pod{{DesiredState: volState}}, true, "one state"}, - {api.Pod{DesiredState: volState}, []api.Pod{{DesiredState: volState}}, false, "same state"}, - {api.Pod{DesiredState: volState2}, []api.Pod{{DesiredState: volState}}, true, "different state"}, + {api.Pod{}, []api.Pod{{Spec: volState}}, true, "one state"}, + {api.Pod{Spec: volState}, []api.Pod{{Spec: volState}}, false, "same state"}, + {api.Pod{Spec: volState2}, []api.Pod{{Spec: volState}}, true, "different state"}, } for _, test := range tests { @@ -286,8 +280,10 @@ func TestPodFitsSelector(t *testing.T) { }, { pod: api.Pod{ - NodeSelector: map[string]string{ - "foo": "bar", + Spec: api.PodSpec{ + NodeSelector: map[string]string{ + "foo": "bar", + }, }, }, fits: false, @@ -295,8 +291,10 @@ func TestPodFitsSelector(t *testing.T) { }, { pod: api.Pod{ - NodeSelector: map[string]string{ - "foo": "bar", + Spec: api.PodSpec{ + NodeSelector: map[string]string{ + "foo": "bar", + }, }, }, labels: map[string]string{ @@ -307,8 +305,10 @@ func TestPodFitsSelector(t *testing.T) { }, { pod: api.Pod{ - NodeSelector: map[string]string{ - "foo": "bar", + Spec: api.PodSpec{ + NodeSelector: map[string]string{ + "foo": "bar", + }, }, }, labels: map[string]string{ @@ -320,9 +320,11 @@ func TestPodFitsSelector(t *testing.T) { }, { pod: api.Pod{ - NodeSelector: map[string]string{ - "foo": "bar", - "baz": "blah", + Spec: api.PodSpec{ + NodeSelector: map[string]string{ + "foo": "bar", + "baz": "blah", + }, }, }, labels: map[string]string{ diff --git a/pkg/scheduler/priorities.go b/pkg/scheduler/priorities.go index 5fb3118a844ad..8b9ff19b99d7e 100644 --- a/pkg/scheduler/priorities.go +++ b/pkg/scheduler/priorities.go @@ -35,7 +35,7 @@ func calculateOccupancy(node api.Minion, pods []api.Pod) HostPriority { totalCPU := 0 totalMemory := 0 for _, pod := range pods { - for _, container := range pod.DesiredState.Manifest.Containers { + for _, container := range pod.Spec.Containers { totalCPU += container.CPU totalMemory += container.Memory } diff --git a/pkg/scheduler/priorities_test.go b/pkg/scheduler/priorities_test.go index 5c5841c2b04b9..e17f46b6491ee 100644 --- a/pkg/scheduler/priorities_test.go +++ b/pkg/scheduler/priorities_test.go @@ -46,29 +46,24 @@ func TestLeastRequested(t *testing.T) { "bar": "foo", "baz": "blah", } - machine1State := api.PodState{ + machine1Status := api.PodStatus{ Host: "machine1", } - machine2State := api.PodState{ + machine2Status := api.PodStatus{ Host: "machine2", } - cpuOnly := api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - {CPU: 1000}, - {CPU: 2000}, - }, + cpuOnly := api.PodSpec{ + Containers: []api.Container{ + {CPU: 1000}, + {CPU: 2000}, }, - Host: "machine1", + // Host: "machine1", } - cpuAndMemory := api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - {CPU: 1000, Memory: 2000}, - {CPU: 2000, Memory: 3000}, - }, + cpuAndMemory := api.PodSpec{ + Containers: []api.Container{ + {CPU: 1000, Memory: 2000}, + {CPU: 2000, Memory: 3000}, }, - Host: "machine2", } tests := []struct { pod api.Pod @@ -87,10 +82,10 @@ func TestLeastRequested(t *testing.T) { expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, test: "no resources requested", pods: []api.Pod{ - {DesiredState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {DesiredState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {DesiredState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {DesiredState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, }, }, { @@ -98,8 +93,8 @@ func TestLeastRequested(t *testing.T) { expectedList: []HostPriority{{"machine1", 37 /* int(75% / 2) */}, {"machine2", 62 /* int( 75% + 50% / 2) */}}, test: "no resources requested", pods: []api.Pod{ - {DesiredState: cpuOnly}, - {DesiredState: cpuAndMemory}, + {Spec: cpuOnly, Status: api.PodStatus{Host: "machine1"}}, + {Spec: cpuAndMemory, Status: api.PodStatus{Host: "machine2"}}, }, }, { @@ -107,8 +102,8 @@ func TestLeastRequested(t *testing.T) { expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, test: "zero minion resources", pods: []api.Pod{ - {DesiredState: cpuOnly}, - {DesiredState: cpuAndMemory}, + {Spec: cpuOnly}, + {Spec: cpuAndMemory}, }, }, } diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 7aa6c0edc6260..7cd296e159214 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -65,15 +65,13 @@ func newPod(host string, hostPorts ...int) api.Pod { networkPorts = append(networkPorts, api.Port{HostPort: port}) } return api.Pod{ - CurrentState: api.PodState{ + Status: api.PodStatus{ Host: host, }, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Ports: networkPorts, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Ports: networkPorts, }, }, }, diff --git a/pkg/scheduler/spreading.go b/pkg/scheduler/spreading.go index 907047c1453b1..751d7f45195ff 100644 --- a/pkg/scheduler/spreading.go +++ b/pkg/scheduler/spreading.go @@ -39,7 +39,7 @@ func CalculateSpreadPriority(pod api.Pod, podLister PodLister, minionLister Mini counts := map[string]int{} for _, pod := range pods { - counts[pod.CurrentState.Host]++ + counts[pod.Status.Host]++ } result := []HostPriority{} diff --git a/pkg/scheduler/spreading_test.go b/pkg/scheduler/spreading_test.go index 73f47585d40b7..4301fd40f7bd7 100644 --- a/pkg/scheduler/spreading_test.go +++ b/pkg/scheduler/spreading_test.go @@ -32,10 +32,10 @@ func TestSpreadPriority(t *testing.T) { "bar": "foo", "baz": "blah", } - machine1State := api.PodState{ + machine1Status := api.PodStatus{ Host: "machine1", } - machine2State := api.PodState{ + machine2Status := api.PodStatus{ Host: "machine2", } tests := []struct { @@ -52,14 +52,14 @@ func TestSpreadPriority(t *testing.T) { }, { pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, - pods: []api.Pod{{CurrentState: machine1State}}, + pods: []api.Pod{{Status: machine1Status}}, nodes: []string{"machine1", "machine2"}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, test: "no labels", }, { pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, - pods: []api.Pod{{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}}, + pods: []api.Pod{{Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}}}, nodes: []string{"machine1", "machine2"}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, test: "different labels", @@ -67,8 +67,8 @@ func TestSpreadPriority(t *testing.T) { { pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pods: []api.Pod{ - {CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, }, nodes: []string{"machine1", "machine2"}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 1}}, @@ -77,9 +77,9 @@ func TestSpreadPriority(t *testing.T) { { pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pods: []api.Pod{ - {CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, }, nodes: []string{"machine1", "machine2"}, expectedList: []HostPriority{{"machine1", 1}, {"machine2", 1}}, @@ -88,10 +88,10 @@ func TestSpreadPriority(t *testing.T) { { pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pods: []api.Pod{ - {CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, - {CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, - {CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}}, + {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, + {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}}, }, nodes: []string{"machine1", "machine2"}, expectedList: []HostPriority{{"machine1", 1}, {"machine2", 2}}, diff --git a/pkg/service/endpoints_controller.go b/pkg/service/endpoints_controller.go index 6fd0d963467dc..08fafa7de1553 100644 --- a/pkg/service/endpoints_controller.go +++ b/pkg/service/endpoints_controller.go @@ -64,17 +64,18 @@ func (e *EndpointController) SyncServiceEndpoints() error { continue } endpoints := []string{} + for _, pod := range pods.Items { - port, err := findPort(&pod.DesiredState.Manifest, service.Spec.ContainerPort) + port, err := findPort(&pod, service.Spec.ContainerPort) if err != nil { glog.Errorf("Failed to find port for service: %v, %v", service, err) continue } - if len(pod.CurrentState.PodIP) == 0 { + if len(pod.Status.PodIP) == 0 { glog.Errorf("Failed to find an IP for pod: %v", pod) continue } - endpoints = append(endpoints, net.JoinHostPort(pod.CurrentState.PodIP, strconv.Itoa(port))) + endpoints = append(endpoints, net.JoinHostPort(pod.Status.PodIP, strconv.Itoa(port))) } currentEndpoints, err := e.client.Endpoints(service.Namespace).Get(service.Name) if err != nil { @@ -137,10 +138,10 @@ func endpointsEqual(e *api.Endpoints, endpoints []string) bool { } // findPort locates the container port for the given manifest and portName. -func findPort(manifest *api.ContainerManifest, portName util.IntOrString) (int, error) { +func findPort(pod *api.Pod, portName util.IntOrString) (int, error) { firstContainerPort := 0 - if len(manifest.Containers[0].Ports) > 0 { - firstContainerPort = manifest.Containers[0].Ports[0].ContainerPort + if len(pod.Spec.Containers) > 0 && len(pod.Spec.Containers[0].Ports) > 0 { + firstContainerPort = pod.Spec.Containers[0].Ports[0].ContainerPort } switch portName.Kind { @@ -152,7 +153,7 @@ func findPort(manifest *api.ContainerManifest, portName util.IntOrString) (int, break } name := portName.StrVal - for _, container := range manifest.Containers { + for _, container := range pod.Spec.Containers { for _, port := range container.Ports { if port.Name == name { return port.ContainerPort, nil @@ -169,5 +170,5 @@ func findPort(manifest *api.ContainerManifest, portName util.IntOrString) (int, return portName.IntVal, nil } - return 0, fmt.Errorf("no suitable port for manifest: %s", manifest.ID) + return 0, fmt.Errorf("no suitable port for manifest: %s", pod.UID) } diff --git a/pkg/service/endpoints_controller_test.go b/pkg/service/endpoints_controller_test.go index 319dac157c67e..00e570bfc6c1d 100644 --- a/pkg/service/endpoints_controller_test.go +++ b/pkg/service/endpoints_controller_test.go @@ -36,20 +36,18 @@ func newPodList(count int) *api.PodList { pods = append(pods, api.Pod{ TypeMeta: api.TypeMeta{APIVersion: testapi.Version()}, ObjectMeta: api.ObjectMeta{Name: fmt.Sprintf("pod%d", i)}, - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Containers: []api.Container{ - { - Ports: []api.Port{ - { - ContainerPort: 8080, - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Ports: []api.Port{ + { + ContainerPort: 8080, }, }, }, }, }, - CurrentState: api.PodState{ + Status: api.PodStatus{ PodIP: "1.2.3.4", }, }) @@ -61,95 +59,101 @@ func newPodList(count int) *api.PodList { } func TestFindPort(t *testing.T) { - manifest := api.ContainerManifest{ - Containers: []api.Container{ - { - Ports: []api.Port{ - { - Name: "foo", - ContainerPort: 8080, - HostPort: 9090, - }, - { - Name: "bar", - ContainerPort: 8000, - HostPort: 9000, + pod := api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Ports: []api.Port{ + { + Name: "foo", + ContainerPort: 8080, + HostPort: 9090, + }, + { + Name: "bar", + ContainerPort: 8000, + HostPort: 9000, + }, }, }, }, }, } - emptyPortsManifest := api.ContainerManifest{ - Containers: []api.Container{ - { - Ports: []api.Port{}, + + emptyPortsPod := api.Pod{ + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Ports: []api.Port{}, + }, }, }, } + tests := []struct { - manifest api.ContainerManifest + pod api.Pod portName util.IntOrString wport int werr bool }{ { - manifest, + pod, util.IntOrString{Kind: util.IntstrString, StrVal: "foo"}, 8080, false, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrString, StrVal: "bar"}, 8000, false, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrInt, IntVal: 8000}, 8000, false, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrInt, IntVal: 7000}, 7000, false, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrString, StrVal: "baz"}, 0, true, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrString, StrVal: ""}, 8080, false, }, { - manifest, + pod, util.IntOrString{Kind: util.IntstrInt, IntVal: 0}, 8080, false, }, { - emptyPortsManifest, + emptyPortsPod, util.IntOrString{Kind: util.IntstrString, StrVal: ""}, 0, true, }, { - emptyPortsManifest, + emptyPortsPod, util.IntOrString{Kind: util.IntstrInt, IntVal: 0}, 0, true, }, } for _, test := range tests { - port, err := findPort(&test.manifest, test.portName) + port, err := findPort(&test.pod, test.portName) if port != test.wport { t.Errorf("Expected port %d, Got %d", test.wport, port) } diff --git a/plugin/pkg/scheduler/factory/factory.go b/plugin/pkg/scheduler/factory/factory.go index 122636939ee50..3951ef3a41705 100644 --- a/plugin/pkg/scheduler/factory/factory.go +++ b/plugin/pkg/scheduler/factory/factory.go @@ -192,7 +192,7 @@ func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue glog.Errorf("Error getting pod %v for retry: %v; abandoning", podID, err) return } - if pod.DesiredState.Host == "" { + if pod.Status.Host == "" { podQueue.Add(pod.Name, pod) } }() diff --git a/test/integration/client_test.go b/test/integration/client_test.go index 44df24ff45fdf..bfccfb978612c 100644 --- a/test/integration/client_test.go +++ b/test/integration/client_test.go @@ -79,24 +79,22 @@ func TestClient(t *testing.T) { // get a validation error pod := &api.Pod{ - DesiredState: api.PodState{ - Manifest: api.ContainerManifest{ - Version: "v1beta2", - Containers: []api.Container{ - { - Name: "test", - }, + Spec: api.PodSpec{ + Containers: []api.Container{ + { + Name: "test", }, }, }, } + got, err := client.Pods(ns).Create(pod) if err == nil { - t.Fatalf("unexpected non-error: %v", err) + t.Fatalf("unexpected non-error: %v", got) } // get a created pod - pod.DesiredState.Manifest.Containers[0].Image = "an-image" + pod.Spec.Containers[0].Image = "an-image" got, err = client.Pods(ns).Create(pod) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -117,7 +115,7 @@ func TestClient(t *testing.T) { if actual.Name != got.Name { t.Errorf("expected pod %#v, got %#v", got, actual) } - if actual.CurrentState.Host != "" { + if actual.Status.Host != "" { t.Errorf("expected pod to be unscheduled, got %#v", actual) } }