v1beta3 Pod refactor

This commit is contained in:
markturansky 2014-11-13 10:52:13 -05:00
parent df0981bc01
commit 8af4ccb111
36 changed files with 569 additions and 573 deletions

View File

@ -46,10 +46,10 @@ func waitForPodRunning(c *client.Client, id string) {
glog.Warningf("Get pod failed: %v", err) glog.Warningf("Get pod failed: %v", err)
continue continue
} }
if pod.CurrentState.Status == api.PodRunning { if pod.Status.Condition == api.PodRunning {
break 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 value = "time" + value
pod.Labels["time"] = value pod.Labels["time"] = value
pod.ResourceVersion = podOut.ResourceVersion pod.ResourceVersion = podOut.ResourceVersion
pod.DesiredState.Manifest.UUID = podOut.DesiredState.Manifest.UUID pod.UID = podOut.UID
pod, err = podClient.Update(pod) pod, err = podClient.Update(pod)
if err != nil { if err != nil {
glog.Errorf("Failed to update pod: %v", err) glog.Errorf("Failed to update pod: %v", err)

View File

@ -216,7 +216,7 @@ func podsOnMinions(c *client.Client, pods api.PodList) wait.ConditionFunc {
podInfo := fakeKubeletClient{} podInfo := fakeKubeletClient{}
return func() (bool, error) { return func() (bool, error) {
for i := range pods.Items { 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 { if len(host) == 0 {
return false, nil return false, nil
} }
@ -499,9 +499,7 @@ func runServiceTest(client *client.Client) {
"name": "thisisalonglabel", "name": "thisisalonglabel",
}, },
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Version: "v1beta1",
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "c1", Name: "c1",
@ -512,8 +510,7 @@ func runServiceTest(client *client.Client) {
}, },
}, },
}, },
}, Status: api.PodStatus{
CurrentState: api.PodState{
PodIP: "1.2.3.4", PodIP: "1.2.3.4",
}, },
} }

View File

@ -81,7 +81,7 @@ func init() {
// Convert Pod to BoundPod // Convert Pod to BoundPod
func(in *Pod, out *BoundPod, s conversion.Scope) error { 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 return err
} }
// Only copy a subset of fields, and override manifest attributes with the pod // Only copy a subset of fields, and override manifest attributes with the pod

View File

@ -45,6 +45,16 @@ func Codec() runtime.Codec {
return interfaces.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, // MetadataAccessor returns the MetadataAccessor for the API version to test against,
// as set by the KUBE_API_VERSION env var. // as set by the KUBE_API_VERSION env var.
func MetadataAccessor() meta.MetadataAccessor { func MetadataAccessor() meta.MetadataAccessor {

View File

@ -455,15 +455,37 @@ type PodSpec struct {
NodeSelector map[string]string `json:"nodeSelector,omitempty" yaml:"nodeSelector,omitempty"` 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). // Pod is a collection of containers, used as either input (create, update) or as output (list, get).
type Pod struct { type Pod struct {
TypeMeta `json:",inline" yaml:",inline"` TypeMeta `json:",inline" yaml:",inline"`
ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"` ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
DesiredState PodState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"` // Spec defines the behavior of a pod.
CurrentState PodState `json:"currentState,omitempty" yaml:"currentState,omitempty"` Spec PodSpec `json:"spec,omitempty" yaml:"spec,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"` // 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 // PodTemplateSpec describes the data a pod should have when created from a template

View File

@ -160,6 +160,32 @@ func init() {
return nil 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 // Convert all to the new PodCondition constants
func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error { func(in *newer.PodCondition, out *PodStatus, s conversion.Scope) error {
switch *in { switch *in {
@ -189,7 +215,7 @@ func init() {
case PodRunning: case PodRunning:
*out = newer.PodRunning *out = newer.PodRunning
case PodTerminated: 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 *out = newer.PodFailed
default: default:
return errors.New("The string provided is not a valid PodCondition constant value") 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 { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil {
return err return err
} }
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil {
return err 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 return err
} }
if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil {
if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil {
return err return err
} }
return nil return nil
@ -231,15 +255,13 @@ func init() {
if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil {
return err return err
} }
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil {
return err 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 return err
} }
if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil {
if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil {
return err return err
} }
return nil return nil
@ -326,6 +348,19 @@ func init() {
return nil 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 { func(in *newer.PodSpec, out *ContainerManifest, s conversion.Scope) error {
if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil { if err := s.Convert(&in.Volumes, &out.Volumes, 0); err != nil {
return err return err

View File

@ -119,7 +119,7 @@ func init() {
case PodRunning: case PodRunning:
*out = newer.PodRunning *out = newer.PodRunning
case PodTerminated: 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 *out = newer.PodFailed
default: default:
return errors.New("The string provided is not a valid PodCondition constant value") 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 { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil {
return err return err
} }
if err := s.Convert(&in.Spec, &out.DesiredState.Manifest, 0); err != nil {
if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil {
return err 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 return err
} }
if err := s.Convert(&in.Spec.NodeSelector, &out.NodeSelector, 0); err != nil {
if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil {
return err return err
} }
return nil return nil
@ -161,15 +159,13 @@ func init() {
if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil { if err := s.Convert(&in.Labels, &out.Labels, 0); err != nil {
return err return err
} }
if err := s.Convert(&in.DesiredState.Manifest, &out.Spec, 0); err != nil {
if err := s.Convert(&in.DesiredState, &out.DesiredState, 0); err != nil {
return err 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 return err
} }
if err := s.Convert(&in.NodeSelector, &out.Spec.NodeSelector, 0); err != nil {
if err := s.Convert(&in.NodeSelector, &out.NodeSelector, 0); err != nil {
return err return err
} }
return nil return nil
@ -282,6 +278,43 @@ func init() {
return nil 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 { func(in *newer.Service, out *Service, s conversion.Scope) error {
if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil { if err := s.Convert(&in.TypeMeta, &out.TypeMeta, 0); err != nil {
return err return err

View File

@ -345,7 +345,7 @@ func ValidatePod(pod *api.Pod) errs.ValidationErrorList {
if !util.IsDNSSubdomain(pod.Namespace) { if !util.IsDNSSubdomain(pod.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", 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)...) allErrs = append(allErrs, validateLabels(pod.Labels)...)
return allErrs return allErrs
} }
@ -383,8 +383,8 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
allErrs = append(allErrs, errs.NewFieldInvalid("name", newPod.Name)) allErrs = append(allErrs, errs.NewFieldInvalid("name", newPod.Name))
} }
if len(newPod.DesiredState.Manifest.Containers) != len(oldPod.DesiredState.Manifest.Containers) { if len(newPod.Spec.Containers) != len(oldPod.Spec.Containers) {
allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers)) allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers))
return allErrs return allErrs
} }
pod := *newPod pod := *newPod
@ -392,13 +392,13 @@ func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
pod.ResourceVersion = oldPod.ResourceVersion pod.ResourceVersion = oldPod.ResourceVersion
// Tricky, we need to copy the container list so that we don't overwrite the update // Tricky, we need to copy the container list so that we don't overwrite the update
var newContainers []api.Container var newContainers []api.Container
for ix, container := range pod.DesiredState.Manifest.Containers { for ix, container := range pod.Spec.Containers {
container.Image = oldPod.DesiredState.Manifest.Containers[ix].Image container.Image = oldPod.Spec.Containers[ix].Image
newContainers = append(newContainers, container) newContainers = append(newContainers, container)
} }
pod.DesiredState.Manifest.Containers = newContainers pod.Spec.Containers = newContainers
if !reflect.DeepEqual(pod.DesiredState.Manifest, oldPod.DesiredState.Manifest) { if !reflect.DeepEqual(pod.Spec, oldPod.Spec) {
allErrs = append(allErrs, errs.NewFieldInvalid("DesiredState.Manifest.Containers", newPod.DesiredState.Manifest.Containers)) allErrs = append(allErrs, errs.NewFieldInvalid("spec.containers", newPod.Spec.Containers))
} }
return allErrs return allErrs
} }

View File

@ -374,15 +374,11 @@ func TestValidatePod(t *testing.T) {
"foo": "bar", "foo": "bar",
}, },
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Version: "v1beta1",
ID: "abc",
RestartPolicy: api.RestartPolicy{ RestartPolicy: api.RestartPolicy{
Always: &api.RestartPolicyAlways{}, Always: &api.RestartPolicyAlways{},
}, },
}, },
},
}) })
if len(errs) != 0 { if len(errs) != 0 {
t.Errorf("Unexpected non-zero error list: %#v", errs) t.Errorf("Unexpected non-zero error list: %#v", errs)
@ -395,28 +391,16 @@ func TestValidatePod(t *testing.T) {
"foo": "bar", "foo": "bar",
}, },
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{},
Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"},
},
}) })
if len(errs) != 0 { if len(errs) != 0 {
t.Errorf("Unexpected non-zero error list: %#v", errs) t.Errorf("Unexpected non-zero error list: %#v", errs)
} }
errs = ValidatePod(&api.Pod{ errs = ValidatePodSpec(&api.PodSpec{
ObjectMeta: api.ObjectMeta{ RestartPolicy: api.RestartPolicy{
Name: "foo", Namespace: api.NamespaceDefault, Always: &api.RestartPolicyAlways{},
Labels: map[string]string{ Never: &api.RestartPolicyNever{},
"foo": "bar",
},
},
DesiredState: api.PodState{
Manifest: api.ContainerManifest{
Version: "v1beta1",
ID: "abc",
RestartPolicy: api.RestartPolicy{Always: &api.RestartPolicyAlways{},
Never: &api.RestartPolicyNever{}},
},
}, },
}) })
if len(errs) != 1 { if len(errs) != 1 {
@ -436,9 +420,7 @@ func TestValidatePod(t *testing.T) {
"rfc952-24chars-orless": "bar", //good label "rfc952-24chars-orless": "bar", //good label
}, },
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{},
Manifest: api.ContainerManifest{Version: "v1beta1", ID: "abc"},
},
}) })
if len(errs) != 5 { if len(errs) != 5 {
t.Errorf("Unexpected non-zero error list: %#v", errs) t.Errorf("Unexpected non-zero error list: %#v", errs)
@ -488,8 +470,7 @@ func TestValidatePodUpdate(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V1", Image: "foo:V1",
@ -497,11 +478,9 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V2", Image: "foo:V2",
@ -512,15 +491,13 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
false, false,
"more containers", "more containers",
}, },
{ {
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V1", Image: "foo:V1",
@ -528,11 +505,9 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V2", Image: "foo:V2",
@ -540,15 +515,13 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
true, true,
"image change", "image change",
}, },
{ {
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V1", Image: "foo:V1",
@ -557,11 +530,9 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V2", Image: "foo:V2",
@ -570,15 +541,13 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
false, false,
"cpu change", "cpu change",
}, },
{ {
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V1", Image: "foo:V1",
@ -589,11 +558,9 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
api.Pod{ api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:V2", Image: "foo:V2",
@ -604,7 +571,6 @@ func TestValidatePodUpdate(t *testing.T) {
}, },
}, },
}, },
},
false, false,
"port change", "port change",
}, },

View File

@ -172,8 +172,8 @@ func TestListPods(t *testing.T) {
Body: &api.PodList{ Body: &api.PodList{
Items: []api.Pod{ Items: []api.Pod{
{ {
CurrentState: api.PodState{ Status: api.PodStatus{
Status: api.PodRunning, Condition: api.PodRunning,
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
@ -205,8 +205,8 @@ func TestListPodsLabels(t *testing.T) {
Body: &api.PodList{ Body: &api.PodList{
Items: []api.Pod{ Items: []api.Pod{
{ {
CurrentState: api.PodState{ Status: api.PodStatus{
Status: api.PodRunning, Condition: api.PodRunning,
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
@ -233,8 +233,8 @@ func TestGetPod(t *testing.T) {
Response: Response{ Response: Response{
StatusCode: 200, StatusCode: 200,
Body: &api.Pod{ Body: &api.Pod{
CurrentState: api.PodState{ Status: api.PodStatus{
Status: api.PodRunning, Condition: api.PodRunning,
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
@ -260,8 +260,8 @@ func TestDeletePod(t *testing.T) {
func TestCreatePod(t *testing.T) { func TestCreatePod(t *testing.T) {
requestPod := &api.Pod{ requestPod := &api.Pod{
CurrentState: api.PodState{ Status: api.PodStatus{
Status: api.PodRunning, Condition: api.PodRunning,
}, },
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: map[string]string{ Labels: map[string]string{
@ -291,8 +291,8 @@ func TestUpdatePod(t *testing.T) {
"name": "baz", "name": "baz",
}, },
}, },
CurrentState: api.PodState{ Status: api.PodStatus{
Status: api.PodRunning, Condition: api.PodRunning,
}, },
} }
c := &testClient{ c := &testClient{

View File

@ -62,7 +62,7 @@ func (r RealPodControl) createReplica(namespace string, controller api.Replicati
Labels: desiredLabels, 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) glog.Errorf("Unable to convert pod template: %v", err)
return return
} }
@ -143,8 +143,8 @@ func (rm *ReplicationManager) watchControllers(resourceVersion *string) {
func (rm *ReplicationManager) filterActivePods(pods []api.Pod) []api.Pod { func (rm *ReplicationManager) filterActivePods(pods []api.Pod) []api.Pod {
var result []api.Pod var result []api.Pod
for _, value := range pods { for _, value := range pods {
if api.PodSucceeded != value.CurrentState.Status && if api.PodSucceeded != value.Status.Condition &&
api.PodFailed != value.CurrentState.Status { api.PodFailed != value.Status.Condition {
result = append(result, value) result = append(result, value)
} }
} }

View File

@ -219,9 +219,7 @@ func TestCreateReplica(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Labels: controllerSpec.Spec.Template.Labels, Labels: controllerSpec.Spec.Template.Labels,
}, },
DesiredState: api.PodState{ Spec: controllerSpec.Spec.Template.Spec,
Manifest: manifest,
},
} }
fakeHandler.ValidateRequest(t, makeURL("/pods?namespace=default"), "POST", nil) fakeHandler.ValidateRequest(t, makeURL("/pods?namespace=default"), "POST", nil)
actualPod, err := client.Codec.Decode([]byte(fakeHandler.RequestBody)) actualPod, err := client.Codec.Decode([]byte(fakeHandler.RequestBody))

View File

@ -71,9 +71,7 @@ func TestParsePod(t *testing.T) {
DoParseTest(t, "pods", &api.Pod{ DoParseTest(t, "pods", &api.Pod{
TypeMeta: api.TypeMeta{APIVersion: "v1beta1", Kind: "Pod"}, TypeMeta: api.TypeMeta{APIVersion: "v1beta1", Kind: "Pod"},
ObjectMeta: api.ObjectMeta{Name: "test pod"}, ObjectMeta: api.ObjectMeta{Name: "test pod"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
ID: "My manifest",
Containers: []api.Container{ Containers: []api.Container{
{Name: "my container"}, {Name: "my container"},
}, },
@ -81,7 +79,6 @@ func TestParsePod(t *testing.T) {
{Name: "volume"}, {Name: "volume"},
}, },
}, },
},
}, v1beta1.Codec, testParser) }, v1beta1.Codec, testParser)
} }

View File

@ -177,7 +177,7 @@ func (h *HumanReadablePrinter) printHeader(columnNames []string, w io.Writer) er
return err return err
} }
func makeImageList(manifest api.ContainerManifest) string { func makeImageList(manifest api.PodSpec) string {
var images []string var images []string
for _, container := range manifest.Containers { for _, container := range manifest.Containers {
images = append(images, container.Image) images = append(images, container.Image)
@ -202,9 +202,9 @@ func podHostString(host, ip string) string {
func printPod(pod *api.Pod, w io.Writer) error { func printPod(pod *api.Pod, w io.Writer) error {
_, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
pod.Name, makeImageList(pod.DesiredState.Manifest), pod.Name, makeImageList(pod.Spec),
podHostString(pod.CurrentState.Host, pod.CurrentState.HostIP), podHostString(pod.Status.Host, pod.Status.HostIP),
labels.Set(pod.Labels), pod.CurrentState.Status) labels.Set(pod.Labels), pod.Status.Condition)
return err return err
} }

View File

@ -35,7 +35,7 @@ func NewCmdLog(out io.Writer) *cobra.Command {
data, err := client.RESTClient.Get(). data, err := client.RESTClient.Get().
Path("proxy/minions"). Path("proxy/minions").
Path(pod.CurrentState.Host). Path(pod.Status.Host).
Path("containerLogs"). Path("containerLogs").
Path(getKubeNamespace(cmd)). Path(getKubeNamespace(cmd)).
Path(args[0]). Path(args[0]).

View File

@ -82,7 +82,7 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) {
// TODO: remove me when pods are converted // TODO: remove me when pods are converted
spec := &api.PodSpec{} 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) 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 { return tabbedString(func(out io.Writer) error {
fmt.Fprintf(out, "Name:\t%s\n", pod.Name) fmt.Fprintf(out, "Name:\t%s\n", pod.Name)
fmt.Fprintf(out, "Image(s):\t%s\n", makeImageList(spec)) 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, "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))) fmt.Fprintf(out, "Replication Controllers:\t%s\n", getReplicationControllersForLabels(rc, labels.Set(pod.Labels)))
if events != nil { if events != nil {
describeEvents(events, out) describeEvents(events, out)
@ -247,7 +247,7 @@ func getPodStatusForReplicationController(c client.PodInterface, controller *api
return return
} }
for _, pod := range rcPods.Items { for _, pod := range rcPods.Items {
switch pod.CurrentState.Status { switch pod.Status.Condition {
case api.PodRunning: case api.PodRunning:
running++ running++
case api.PodPending: case api.PodPending:

View File

@ -257,7 +257,7 @@ func podHostString(host, ip string) string {
func printPod(pod *api.Pod, w io.Writer) error { func printPod(pod *api.Pod, w io.Writer) error {
// TODO: remove me when pods are converted // TODO: remove me when pods are converted
spec := &api.PodSpec{} 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) glog.Errorf("Unable to convert pod manifest: %v", err)
} }
il := listOfImages(spec) 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", _, err := fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
pod.Name, firstImage, pod.Name, firstImage,
podHostString(pod.CurrentState.Host, pod.CurrentState.HostIP), podHostString(pod.Status.Host, pod.Status.HostIP),
labels.Set(pod.Labels), pod.CurrentState.Status) labels.Set(pod.Labels), pod.Status.Condition)
if err != nil { if err != nil {
return err return err
} }

View File

@ -84,10 +84,10 @@ func (p *PodCache) UpdateAllContainers() {
return return
} }
for _, pod := range pods.Items { for _, pod := range pods.Items {
if pod.CurrentState.Host == "" { if pod.Status.Host == "" {
continue 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 { if err != nil && err != client.ErrPodInfoNotAvailable {
glog.Errorf("Error synchronizing container: %v", err) glog.Errorf("Error synchronizing container: %v", err)
} }

View File

@ -125,7 +125,7 @@ func TestPodGetPodInfoGetter(t *testing.T) {
func TestPodUpdateAllContainers(t *testing.T) { func TestPodUpdateAllContainers(t *testing.T) {
pod := api.Pod{ pod := api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault}, ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
CurrentState: api.PodState{ Status: api.PodStatus{
Host: "machine", Host: "machine",
}, },
} }

View File

@ -114,10 +114,6 @@ func (r *Registry) ListPodsPredicate(ctx api.Context, filter func(*api.Pod) bool
filtered := []api.Pod{} filtered := []api.Pod{}
for _, pod := range allPods.Items { for _, pod := range allPods.Items {
if filter(&pod) { 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) 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 { if err = r.ExtractObj(key, &pod, false); err != nil {
return nil, etcderr.InterpretGetError(err, "pod", id) 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 return &pod, nil
} }
@ -167,11 +159,8 @@ func makeContainerKey(machine string) string {
// CreatePod creates a pod based on a specification. // CreatePod creates a pod based on a specification.
func (r *Registry) CreatePod(ctx api.Context, pod *api.Pod) error { func (r *Registry) CreatePod(ctx api.Context, pod *api.Pod) error {
// Set current status to "Waiting". // Set current status to "Waiting".
pod.CurrentState.Status = api.PodPending pod.Status.Condition = api.PodPending
pod.CurrentState.Host = "" pod.Status.Host = ""
// DesiredState.Host == "" is a signal to the scheduler that this pod needs scheduling.
pod.DesiredState.Status = api.PodRunning
pod.DesiredState.Host = ""
key, err := makePodKey(ctx, pod.Name) key, err := makePodKey(ctx, pod.Name)
if err != nil { if err != nil {
return err return err
@ -197,10 +186,10 @@ func (r *Registry) setPodHostTo(ctx api.Context, podID, oldMachine, machine stri
if !ok { if !ok {
return nil, fmt.Errorf("unexpected object: %#v", obj) return nil, fmt.Errorf("unexpected object: %#v", obj)
} }
if pod.DesiredState.Host != oldMachine { if pod.Status.Host != oldMachine {
return nil, fmt.Errorf("pod %v is already assigned to host %v", pod.Name, pod.DesiredState.Host) 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 finalPod = pod
return pod, nil return pod, nil
}) })
@ -248,9 +237,9 @@ func (r *Registry) UpdatePod(ctx api.Context, pod *api.Pod) error {
if err != nil { if err != nil {
return err return err
} }
scheduled := podOut.DesiredState.Host != "" scheduled := podOut.Status.Host != ""
if scheduled { 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. // If it's already been scheduled, limit the types of updates we'll accept.
errs := validation.ValidatePodUpdate(pod, &podOut) errs := validation.ValidatePodUpdate(pod, &podOut)
if len(errs) != 0 { if len(errs) != 0 {
@ -267,18 +256,19 @@ func (r *Registry) UpdatePod(ctx api.Context, pod *api.Pod) error {
// never scheduled, just update. // never scheduled, just update.
return nil return nil
} }
containerKey := makeContainerKey(podOut.DesiredState.Host)
return r.AtomicUpdate(containerKey, &api.ContainerManifestList{}, func(in runtime.Object) (runtime.Object, error) { containerKey := makeContainerKey(podOut.Status.Host)
manifests := in.(*api.ContainerManifestList) return r.AtomicUpdate(containerKey, &api.BoundPods{}, func(in runtime.Object) (runtime.Object, error) {
for ix := range manifests.Items { boundPods := in.(*api.BoundPods)
if manifests.Items[ix].ID == pod.Name { for ix := range boundPods.Items {
manifests.Items[ix] = pod.DesiredState.Manifest if boundPods.Items[ix].Name == pod.Name {
return manifests, nil boundPods.Items[ix].Spec = pod.Spec
return boundPods, nil
} }
} }
// This really shouldn't happen // This really shouldn't happen
glog.Warningf("Couldn't find: %s in %#v", pod.Name, manifests) glog.Warningf("Couldn't find: %s in %#v", pod.Name, boundPods)
return manifests, fmt.Errorf("Failed to update pod, couldn't find %s in %#v", pod.Name, manifests) 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 { if err != nil {
return etcderr.InterpretDeleteError(err, "pod", podID) return etcderr.InterpretDeleteError(err, "pod", podID)
} }
machine := pod.DesiredState.Host machine := pod.Status.Host
if machine == "" { if machine == "" {
// Pod was never scheduled anywhere, just return. // Pod was never scheduled anywhere, just return.
return nil return nil

View File

@ -131,15 +131,13 @@ func TestEtcdCreatePod(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -184,15 +182,13 @@ func TestEtcdCreatePodFailsWithoutNamespace(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
// Accept "namespace" or "Namespace". // Accept "namespace" or "Namespace".
if err == nil || !strings.Contains(err.Error(), "amespace") { if err == nil || !strings.Contains(err.Error(), "amespace") {
@ -260,7 +256,7 @@ func TestEtcdCreatePodWithContainersError(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) 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.") t.Fatal("Pod's host changed in response to an non-apply-able binding.")
} }
} }
@ -287,16 +283,13 @@ func TestEtcdCreatePodWithContainersNotFound(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
ID: "foo",
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -354,16 +347,13 @@ func TestEtcdCreatePodWithExistingContainers(t *testing.T) {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
ID: "foo",
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -470,35 +460,38 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
key, _ := makePodKey(ctx, "foo") key, _ := makePodKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Host: "machine", // Host: "machine",
Manifest: api.ContainerManifest{
ID: "foo",
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:v1", Image: "foo:v1",
}, },
}, },
}, },
Status: api.PodStatus{
Host: "machine",
}, },
}), 1) }), 1)
contKey := "/registry/nodes/machine/boundpods" contKey := "/registry/nodes/machine/boundpods"
fakeClient.Set(contKey, runtime.EncodeOrDie(latest.Codec, &api.ContainerManifestList{ fakeClient.Set(contKey, runtime.EncodeOrDie(latest.Codec, &api.BoundPods{
Items: []api.ContainerManifest{ Items: []api.BoundPod{
{ {
ID: "foo", ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:v1", Image: "foo:v1",
}, },
}, },
}, },
{ }, {
ID: "bar", ObjectMeta: api.ObjectMeta{Name: "bar"},
Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "bar:v1", Image: "foo:v1",
},
}, },
}, },
}, },
@ -514,15 +507,15 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
"foo": "bar", "foo": "bar",
}, },
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
ID: "foo",
Containers: []api.Container{ Containers: []api.Container{
{ {
Image: "foo:v2", Image: "foo:v2",
}, },
}, },
}, },
Status: api.PodStatus{
Host: "machine",
}, },
} }
err := registry.UpdatePod(ctx, &podIn) err := registry.UpdatePod(ctx, &podIn)
@ -535,7 +528,6 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
} }
var podOut api.Pod var podOut api.Pod
latest.Codec.DecodeInto([]byte(response.Node.Value), &podOut) latest.Codec.DecodeInto([]byte(response.Node.Value), &podOut)
podIn.DesiredState.Host = "machine"
if !reflect.DeepEqual(podOut, podIn) { if !reflect.DeepEqual(podOut, podIn) {
t.Errorf("expected: %#v, got: %#v", podOut, podIn) t.Errorf("expected: %#v, got: %#v", podOut, podIn)
} }
@ -544,10 +536,13 @@ func TestEtcdUpdatePodScheduled(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var list api.ContainerManifestList var list api.BoundPods
latest.Codec.DecodeInto([]byte(response.Node.Value), &list) if err := latest.Codec.DecodeInto([]byte(response.Node.Value), &list); err != nil {
if len(list.Items) != 2 || !reflect.DeepEqual(list.Items[0], podIn.DesiredState.Manifest) { t.Fatalf("unexpected error decoding response: %v", err)
t.Errorf("unexpected container list: %d %v %v", len(list.Items), list.Items[0], podIn.DesiredState.Manifest) }
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)
} }
} }
@ -559,7 +554,7 @@ func TestEtcdDeletePod(t *testing.T) {
key, _ := makePodKey(ctx, "foo") key, _ := makePodKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
}), 0) }), 0)
fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{ fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{
Items: []api.BoundPod{ Items: []api.BoundPod{
@ -595,7 +590,7 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
key, _ := makePodKey(ctx, "foo") key, _ := makePodKey(ctx, "foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
}), 0) }), 0)
fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{ fakeClient.Set("/registry/nodes/machine/boundpods", runtime.EncodeOrDie(latest.Codec, &api.BoundPods{
Items: []api.BoundPod{ Items: []api.BoundPod{
@ -681,13 +676,13 @@ func TestEtcdListPods(t *testing.T) {
{ {
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
}), }),
}, },
{ {
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "bar"}, ObjectMeta: api.ObjectMeta{Name: "bar"},
DesiredState: api.PodState{Host: "machine"}, 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" { if len(pods.Items) != 2 || pods.Items[0].Name != "foo" || pods.Items[1].Name != "bar" {
t.Errorf("Unexpected pod list: %#v", pods) t.Errorf("Unexpected pod list: %#v", pods)
} }
if pods.Items[0].CurrentState.Host != "machine" || if pods.Items[0].Status.Host != "machine" ||
pods.Items[1].CurrentState.Host != "machine" { pods.Items[1].Status.Host != "machine" {
t.Errorf("Failed to populate host name.") t.Errorf("Failed to populate host name.")
} }
} }

View File

@ -73,11 +73,11 @@ func (EverythingMatcher) Matches(obj runtime.Object) (bool, error) {
func TestEtcdList(t *testing.T) { func TestEtcdList(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
podB := &api.Pod{ podB := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "bar"}, ObjectMeta: api.ObjectMeta{Name: "bar"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
normalListResp := &etcd.Response{ normalListResp := &etcd.Response{
@ -155,11 +155,11 @@ func TestEtcdList(t *testing.T) {
func TestEtcdCreate(t *testing.T) { func TestEtcdCreate(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
podB := &api.Pod{ podB := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine2"}, Status: api.PodStatus{Host: "machine2"},
} }
nodeWithPodA := tools.EtcdResponseWithError{ nodeWithPodA := tools.EtcdResponseWithError{
@ -218,11 +218,11 @@ func TestEtcdCreate(t *testing.T) {
func TestEtcdUpdate(t *testing.T) { func TestEtcdUpdate(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
podB := &api.Pod{ podB := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
DesiredState: api.PodState{Host: "machine2"}, Status: api.PodStatus{Host: "machine2"},
} }
nodeWithPodA := tools.EtcdResponseWithError{ nodeWithPodA := tools.EtcdResponseWithError{
@ -293,7 +293,7 @@ func TestEtcdUpdate(t *testing.T) {
func TestEtcdGet(t *testing.T) { func TestEtcdGet(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
nodeWithPodA := tools.EtcdResponseWithError{ nodeWithPodA := tools.EtcdResponseWithError{
@ -349,7 +349,7 @@ func TestEtcdGet(t *testing.T) {
func TestEtcdDelete(t *testing.T) { func TestEtcdDelete(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
nodeWithPodA := tools.EtcdResponseWithError{ nodeWithPodA := tools.EtcdResponseWithError{
@ -405,7 +405,7 @@ func TestEtcdDelete(t *testing.T) {
func TestEtcdWatch(t *testing.T) { func TestEtcdWatch(t *testing.T) {
podA := &api.Pod{ podA := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"}, ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
DesiredState: api.PodState{Host: "machine"}, Status: api.PodStatus{Host: "machine"},
} }
respWithPodA := &etcd.Response{ respWithPodA := &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{

View File

@ -33,15 +33,13 @@ func TestMakeBoundPodNoServices(t *testing.T) {
pod, err := factory.MakeBoundPod("machine", &api.Pod{ pod, err := factory.MakeBoundPod("machine", &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foobar"}, ObjectMeta: api.ObjectMeta{Name: "foobar"},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -83,15 +81,14 @@ func TestMakeBoundPodServices(t *testing.T) {
} }
pod, err := factory.MakeBoundPod("machine", &api.Pod{ pod, err := factory.MakeBoundPod("machine", &api.Pod{
DesiredState: api.PodState{ ObjectMeta: api.ObjectMeta{Name: "foobar"},
Manifest: api.ContainerManifest{ Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "foo", Name: "foo",
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -161,8 +158,7 @@ func TestMakeBoundPodServicesExistingEnvVar(t *testing.T) {
} }
pod, err := factory.MakeBoundPod("machine", &api.Pod{ pod, err := factory.MakeBoundPod("machine", &api.Pod{
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Env: []api.EnvVar{ Env: []api.EnvVar{
@ -174,7 +170,6 @@ func TestMakeBoundPodServicesExistingEnvVar(t *testing.T) {
}, },
}, },
}, },
},
}) })
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)

View File

@ -29,7 +29,6 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider" "github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
"github.com/golang/glog" "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) { if !api.ValidNamespace(ctx, &pod.ObjectMeta) {
return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context")) 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 { 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 { if errs := validation.ValidatePod(pod); len(errs) > 0 {
return nil, errors.NewInvalid("pod", pod.Name, errs) return nil, errors.NewInvalid("pod", pod.Name, errs)
} }
api.FillObjectMetaSystemFields(ctx, &pod.ObjectMeta)
return apiserver.MakeAsync(func() (runtime.Object, error) { return apiserver.MakeAsync(func() (runtime.Object, error) {
if err := rs.registry.CreatePod(ctx, pod); err != nil { if err := rs.registry.CreatePod(ctx, pod); err != nil {
return nil, err return nil, err
@ -131,10 +128,10 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
if err != nil { if err != nil {
return pod, err return pod, err
} }
pod.CurrentState.Status = status pod.Status.Condition = status
} }
if pod.CurrentState.Host != "" { if pod.Status.Host != "" {
pod.CurrentState.HostIP = rs.getInstanceIP(pod.CurrentState.Host) pod.Status.HostIP = rs.getInstanceIP(pod.Status.Host)
} }
return pod, err return pod, err
} }
@ -142,8 +139,8 @@ func (rs *REST) Get(ctx api.Context, id string) (runtime.Object, error) {
func (rs *REST) podToSelectableFields(pod *api.Pod) labels.Set { func (rs *REST) podToSelectableFields(pod *api.Pod) labels.Set {
return labels.Set{ return labels.Set{
"name": pod.Name, "name": pod.Name,
"DesiredState.Status": string(pod.DesiredState.Status), "Status.Condition": string(pod.Status.Condition),
"DesiredState.Host": pod.DesiredState.Host, "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 { if err != nil {
return pod, err return pod, err
} }
pod.CurrentState.Status = status pod.Status.Condition = status
if pod.CurrentState.Host != "" { if pod.Status.Host != "" {
pod.CurrentState.HostIP = rs.getInstanceIP(pod.CurrentState.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) { func (rs *REST) fillPodInfo(pod *api.Pod) {
pod.CurrentState.Host = pod.DesiredState.Host if pod.Status.Host == "" {
if pod.CurrentState.Host == "" {
return return
} }
// Get cached info for the list currently. // Get cached info for the list currently.
// TODO: Optionally use fresh info // TODO: Optionally use fresh info
if rs.podCache != nil { 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 != nil {
if err != client.ErrPodInfoNotAvailable { if err != client.ErrPodInfoNotAvailable {
glog.Errorf("Error getting container info from cache: %#v", err) glog.Errorf("Error getting container info from cache: %#v", err)
} }
if rs.podInfoGetter != nil { 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 != nil {
if err != client.ErrPodInfoNotAvailable { if err != client.ErrPodInfoNotAvailable {
@ -223,11 +219,11 @@ func (rs *REST) fillPodInfo(pod *api.Pod) {
return return
} }
} }
pod.CurrentState.Info = info pod.Status.Info = info
netContainerInfo, ok := info["net"] netContainerInfo, ok := info["net"]
if ok { if ok {
if netContainerInfo.PodIP != "" { if netContainerInfo.PodIP != "" {
pod.CurrentState.PodIP = netContainerInfo.PodIP pod.Status.PodIP = netContainerInfo.PodIP
} else { } else {
glog.Warningf("No network settings: %#v", netContainerInfo) 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) { func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodCondition, error) {
if pod.CurrentState.Host == "" { if pod.Status.Host == "" {
return api.PodPending, nil return api.PodPending, nil
} }
if minions != nil { if minions != nil {
@ -280,7 +276,7 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodConditio
} }
found := false found := false
for _, minion := range res.Items { for _, minion := range res.Items {
if minion.Name == pod.CurrentState.Host { if minion.Name == pod.Status.Host {
found = true found = true
break break
} }
@ -291,14 +287,14 @@ func getPodStatus(pod *api.Pod, minions client.MinionInterface) (api.PodConditio
} else { } else {
glog.Errorf("Unexpected missing minion interface, status may be in-accurate") 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 return api.PodPending, nil
} }
running := 0 running := 0
stopped := 0 stopped := 0
unknown := 0 unknown := 0
for _, container := range pod.DesiredState.Manifest.Containers { for _, container := range pod.Spec.Containers {
if containerStatus, ok := pod.CurrentState.Info[container.Name]; ok { if containerStatus, ok := pod.Status.Info[container.Name]; ok {
if containerStatus.State.Running != nil { if containerStatus.State.Running != nil {
running++ running++
} else if containerStatus.State.Termination != nil { } else if containerStatus.State.Termination != nil {

View File

@ -28,7 +28,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver" "github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "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/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest" "github.com/GoogleCloudPlatform/kubernetes/pkg/registry/registrytest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/util"
@ -62,12 +62,7 @@ func TestCreatePodRegistryError(t *testing.T) {
storage := REST{ storage := REST{
registry: podRegistry, registry: podRegistry,
} }
desiredState := api.PodState{ pod := &api.Pod{}
Manifest: api.ContainerManifest{
Version: "v1beta1",
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod) ch, err := storage.Create(ctx, pod)
if err != nil { if err != nil {
@ -82,12 +77,7 @@ func TestCreatePodSetsIds(t *testing.T) {
storage := REST{ storage := REST{
registry: podRegistry, registry: podRegistry,
} }
desiredState := api.PodState{ pod := &api.Pod{}
Manifest: api.ContainerManifest{
Version: "v1beta1",
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod) ch, err := storage.Create(ctx, pod)
if err != nil { if err != nil {
@ -98,23 +88,18 @@ func TestCreatePodSetsIds(t *testing.T) {
if len(podRegistry.Pod.Name) == 0 { if len(podRegistry.Pod.Name) == 0 {
t.Errorf("Expected pod ID to be set, Got %#v", pod) 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) 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 := registrytest.NewPodRegistry(nil)
podRegistry.Err = fmt.Errorf("test error") podRegistry.Err = fmt.Errorf("test error")
storage := REST{ storage := REST{
registry: podRegistry, registry: podRegistry,
} }
desiredState := api.PodState{ pod := &api.Pod{}
Manifest: api.ContainerManifest{
Version: "v1beta1",
},
}
pod := &api.Pod{DesiredState: desiredState}
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
ch, err := storage.Create(ctx, pod) ch, err := storage.Create(ctx, pod)
if err != nil { if err != nil {
@ -122,8 +107,8 @@ func TestCreatePodSetsUUIDs(t *testing.T) {
} }
expectApiStatusError(t, ch, podRegistry.Err.Error()) expectApiStatusError(t, ch, podRegistry.Err.Error())
if len(podRegistry.Pod.DesiredState.Manifest.UUID) == 0 { if len(podRegistry.Pod.UID) == 0 {
t.Errorf("Expected pod UUID to be set, Got %#v", pod) t.Errorf("Expected pod UID to be set, Got %#v", pod)
} }
} }
@ -217,10 +202,10 @@ func TestListPodListSelection(t *testing.T) {
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
}, { }, {
ObjectMeta: api.ObjectMeta{Name: "bar"}, ObjectMeta: api.ObjectMeta{Name: "bar"},
DesiredState: api.PodState{Host: "barhost"}, Status: api.PodStatus{Host: "barhost"},
}, { }, {
ObjectMeta: api.ObjectMeta{Name: "baz"}, ObjectMeta: api.ObjectMeta{Name: "baz"},
DesiredState: api.PodState{Status: "bazstatus"}, Status: api.PodStatus{Condition: "bazstatus"},
}, { }, {
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "qux", Name: "qux",
@ -251,16 +236,16 @@ func TestListPodListSelection(t *testing.T) {
label: "label=qux", label: "label=qux",
expectedIDs: util.NewStringSet("qux"), expectedIDs: util.NewStringSet("qux"),
}, { }, {
field: "DesiredState.Status=bazstatus", field: "Status.Condition=bazstatus",
expectedIDs: util.NewStringSet("baz"), expectedIDs: util.NewStringSet("baz"),
}, { }, {
field: "DesiredState.Host=barhost", field: "Status.Host=barhost",
expectedIDs: util.NewStringSet("bar"), expectedIDs: util.NewStringSet("bar"),
}, { }, {
field: "DesiredState.Host=", field: "Status.Host=",
expectedIDs: util.NewStringSet("foo", "baz", "qux", "zot"), expectedIDs: util.NewStringSet("foo", "baz", "qux", "zot"),
}, { }, {
field: "DesiredState.Host!=", field: "Status.Host!=",
expectedIDs: util.NewStringSet("bar"), expectedIDs: util.NewStringSet("bar"),
}, },
} }
@ -342,7 +327,7 @@ func TestGetPod(t *testing.T) {
func TestGetPodCloud(t *testing.T) { func TestGetPodCloud(t *testing.T) {
fakeCloud := &fake_cloud.FakeCloud{} fakeCloud := &fake_cloud.FakeCloud{}
podRegistry := registrytest.NewPodRegistry(nil) 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()} clock := &fakeClock{t: time.Now()}
@ -393,16 +378,13 @@ func TestMakePodStatus(t *testing.T) {
}, },
}, },
} }
desiredState := api.PodState{ desiredState := api.PodSpec{
Manifest: api.ContainerManifest{
Version: "v1beta1",
Containers: []api.Container{ Containers: []api.Container{
{Name: "containerA"}, {Name: "containerA"},
{Name: "containerB"}, {Name: "containerB"},
}, },
},
} }
currentState := api.PodState{ currentState := api.PodStatus{
Host: "machine", Host: "machine",
} }
runningState := api.ContainerStatus{ runningState := api.ContainerStatus{
@ -421,11 +403,11 @@ func TestMakePodStatus(t *testing.T) {
status api.PodCondition status api.PodCondition
test string test string
}{ }{
{&api.Pod{DesiredState: desiredState, CurrentState: currentState}, api.PodPending, "waiting"}, {&api.Pod{Spec: desiredState, Status: currentState}, api.PodPending, "waiting"},
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Host: "machine-2", Host: "machine-2",
}, },
}, },
@ -434,8 +416,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": runningState, "containerA": runningState,
"containerB": runningState, "containerB": runningState,
@ -448,8 +430,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": runningState, "containerA": runningState,
"containerB": runningState, "containerB": runningState,
@ -462,8 +444,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": stoppedState, "containerA": stoppedState,
"containerB": stoppedState, "containerB": stoppedState,
@ -476,8 +458,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": stoppedState, "containerA": stoppedState,
"containerB": stoppedState, "containerB": stoppedState,
@ -490,8 +472,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": runningState, "containerA": runningState,
"containerB": stoppedState, "containerB": stoppedState,
@ -504,8 +486,8 @@ func TestMakePodStatus(t *testing.T) {
}, },
{ {
&api.Pod{ &api.Pod{
DesiredState: desiredState, Spec: desiredState,
CurrentState: api.PodState{ Status: api.PodStatus{
Info: map[string]api.ContainerStatus{ Info: map[string]api.ContainerStatus{
"containerA": runningState, "containerA": runningState,
}, },
@ -533,7 +515,13 @@ func TestPodStorageValidatesCreate(t *testing.T) {
registry: podRegistry, registry: podRegistry,
} }
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
pod := &api.Pod{} pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{
"invalid-label-to-cause-validation-failure": "bar",
},
},
}
c, err := storage.Create(ctx, pod) c, err := storage.Create(ctx, pod)
if c != nil { if c != nil {
t.Errorf("Expected nil channel") t.Errorf("Expected nil channel")
@ -543,28 +531,11 @@ func TestPodStorageValidatesCreate(t *testing.T) {
} }
} }
func TestPodStorageValidatesUpdate(t *testing.T) {
podRegistry := registrytest.NewPodRegistry(nil)
podRegistry.Err = fmt.Errorf("test error")
storage := REST{
registry: podRegistry,
}
ctx := api.NewDefaultContext()
pod := &api.Pod{}
c, err := storage.Update(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 TestCreatePod(t *testing.T) { func TestCreatePod(t *testing.T) {
podRegistry := registrytest.NewPodRegistry(nil) podRegistry := registrytest.NewPodRegistry(nil)
podRegistry.Pod = &api.Pod{ podRegistry.Pod = &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
CurrentState: api.PodState{ Status: api.PodStatus{
Host: "machine", Host: "machine",
}, },
} }
@ -572,15 +543,8 @@ func TestCreatePod(t *testing.T) {
registry: podRegistry, registry: podRegistry,
podPollPeriod: time.Millisecond * 100, podPollPeriod: time.Millisecond * 100,
} }
desiredState := api.PodState{ pod := &api.Pod{}
Manifest: api.ContainerManifest{ pod.Name = "foo"
Version: "v1beta1",
},
}
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
DesiredState: desiredState,
}
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
channel, err := storage.Create(ctx, pod) channel, err := storage.Create(ctx, pod)
if err != nil { if err != nil {
@ -625,13 +589,13 @@ func TestFillPodInfo(t *testing.T) {
storage := REST{ storage := REST{
podCache: &fakeGetter, podCache: &fakeGetter,
} }
pod := api.Pod{DesiredState: api.PodState{Host: "foo"}} pod := api.Pod{Status: api.PodStatus{Host: "foo"}}
storage.fillPodInfo(&pod) storage.fillPodInfo(&pod)
if !reflect.DeepEqual(fakeGetter.info, pod.CurrentState.Info) { if !reflect.DeepEqual(fakeGetter.info, pod.Status.Info) {
t.Errorf("Expected: %#v, Got %#v", fakeGetter.info, pod.CurrentState.Info) t.Errorf("Expected: %#v, Got %#v", fakeGetter.info, pod.Status.Info)
} }
if pod.CurrentState.PodIP != expectedIP { if pod.Status.PodIP != expectedIP {
t.Errorf("Expected %s, Got %s", expectedIP, pod.CurrentState.PodIP) t.Errorf("Expected %s, Got %s", expectedIP, pod.Status.PodIP)
} }
} }
@ -647,13 +611,13 @@ func TestFillPodInfoNoData(t *testing.T) {
storage := REST{ storage := REST{
podCache: &fakeGetter, podCache: &fakeGetter,
} }
pod := api.Pod{DesiredState: api.PodState{Host: "foo"}} pod := api.Pod{Status: api.PodStatus{Host: "foo"}}
storage.fillPodInfo(&pod) storage.fillPodInfo(&pod)
if !reflect.DeepEqual(fakeGetter.info, pod.CurrentState.Info) { if !reflect.DeepEqual(fakeGetter.info, pod.Status.Info) {
t.Errorf("Expected %#v, Got %#v", fakeGetter.info, pod.CurrentState.Info) t.Errorf("Expected %#v, Got %#v", fakeGetter.info, pod.Status.Info)
} }
if pod.CurrentState.PodIP != expectedIP { if pod.Status.PodIP != expectedIP {
t.Errorf("Expected %s, Got %s", expectedIP, pod.CurrentState.PodIP) t.Errorf("Expected %s, Got %s", expectedIP, pod.Status.PodIP)
} }
} }

View File

@ -57,7 +57,7 @@ func isVolumeConflict(volume api.Volume, pod *api.Pod) bool {
} }
pdName := volume.Source.GCEPersistentDisk.PDName pdName := volume.Source.GCEPersistentDisk.PDName
manifest := &(pod.DesiredState.Manifest) manifest := &(pod.Spec)
for ix := range manifest.Volumes { for ix := range manifest.Volumes {
if manifest.Volumes[ix].Source.GCEPersistentDisk != nil && if manifest.Volumes[ix].Source.GCEPersistentDisk != nil &&
manifest.Volumes[ix].Source.GCEPersistentDisk.PDName == pdName { 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. // there. This is GCE specific for now.
// TODO: migrate this into some per-volume specific code? // TODO: migrate this into some per-volume specific code?
func NoDiskConflict(pod api.Pod, existingPods []api.Pod, node string) (bool, error) { 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 ix := range manifest.Volumes {
for podIx := range existingPods { for podIx := range existingPods {
if isVolumeConflict(manifest.Volumes[ix], &existingPods[podIx]) { if isVolumeConflict(manifest.Volumes[ix], &existingPods[podIx]) {
@ -95,9 +95,9 @@ type resourceRequest struct {
func getResourceRequest(pod *api.Pod) resourceRequest { func getResourceRequest(pod *api.Pod) resourceRequest {
result := resourceRequest{} result := resourceRequest{}
for ix := range pod.DesiredState.Manifest.Containers { for ix := range pod.Spec.Containers {
result.memory += pod.DesiredState.Manifest.Containers[ix].Memory result.memory += pod.Spec.Containers[ix].Memory
result.milliCPU += pod.DesiredState.Manifest.Containers[ix].CPU result.milliCPU += pod.Spec.Containers[ix].CPU
} }
return result return result
} }
@ -151,10 +151,10 @@ type NodeSelector struct {
} }
func (n *NodeSelector) PodSelectorMatches(pod api.Pod, existingPods []api.Pod, node string) (bool, error) { 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 return true, nil
} }
selector := labels.SelectorFromSet(pod.NodeSelector) selector := labels.SelectorFromSet(pod.Spec.NodeSelector)
minion, err := n.info.GetNodeInfo(node) minion, err := n.info.GetNodeInfo(node)
if err != nil { if err != nil {
return false, err 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 { func getUsedPorts(pods ...api.Pod) map[int]bool {
ports := make(map[int]bool) ports := make(map[int]bool)
for _, pod := range pods { for _, pod := range pods {
for _, container := range pod.DesiredState.Manifest.Containers { for _, container := range pod.Spec.Containers {
for _, podPort := range container.Ports { for _, podPort := range container.Ports {
ports[podPort.HostPort] = true ports[podPort.HostPort] = true
} }
@ -198,7 +198,7 @@ func MapPodsToMachines(lister PodLister) (map[string][]api.Pod, error) {
return map[string][]api.Pod{}, err return map[string][]api.Pod{}, err
} }
for _, scheduledPod := range pods { for _, scheduledPod := range pods {
host := scheduledPod.DesiredState.Host host := scheduledPod.Status.Host
machineToPods[host] = append(machineToPods[host], scheduledPod) machineToPods[host] = append(machineToPods[host], scheduledPod)
} }
return machineToPods, nil return machineToPods, nil

View File

@ -56,11 +56,9 @@ func newResourcePod(usage ...resourceRequest) api.Pod {
}) })
} }
return api.Pod{ return api.Pod{
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: containers, Containers: containers,
}, },
},
} }
} }
@ -220,8 +218,7 @@ func TestGetUsedPorts(t *testing.T) {
} }
func TestDiskConflicts(t *testing.T) { func TestDiskConflicts(t *testing.T) {
volState := api.PodState{ volState := api.PodSpec{
Manifest: api.ContainerManifest{
Volumes: []api.Volume{ Volumes: []api.Volume{
{ {
Source: &api.VolumeSource{ Source: &api.VolumeSource{
@ -231,10 +228,8 @@ func TestDiskConflicts(t *testing.T) {
}, },
}, },
}, },
},
} }
volState2 := api.PodState{ volState2 := api.PodSpec{
Manifest: api.ContainerManifest{
Volumes: []api.Volume{ Volumes: []api.Volume{
{ {
Source: &api.VolumeSource{ Source: &api.VolumeSource{
@ -244,7 +239,6 @@ func TestDiskConflicts(t *testing.T) {
}, },
}, },
}, },
},
} }
tests := []struct { tests := []struct {
pod api.Pod pod api.Pod
@ -253,9 +247,9 @@ func TestDiskConflicts(t *testing.T) {
test string test string
}{ }{
{api.Pod{}, []api.Pod{}, true, "nothing"}, {api.Pod{}, []api.Pod{}, true, "nothing"},
{api.Pod{}, []api.Pod{{DesiredState: volState}}, true, "one state"}, {api.Pod{}, []api.Pod{{Spec: volState}}, true, "one state"},
{api.Pod{DesiredState: volState}, []api.Pod{{DesiredState: volState}}, false, "same state"}, {api.Pod{Spec: volState}, []api.Pod{{Spec: volState}}, false, "same state"},
{api.Pod{DesiredState: volState2}, []api.Pod{{DesiredState: volState}}, true, "different state"}, {api.Pod{Spec: volState2}, []api.Pod{{Spec: volState}}, true, "different state"},
} }
for _, test := range tests { for _, test := range tests {
@ -286,19 +280,23 @@ func TestPodFitsSelector(t *testing.T) {
}, },
{ {
pod: api.Pod{ pod: api.Pod{
Spec: api.PodSpec{
NodeSelector: map[string]string{ NodeSelector: map[string]string{
"foo": "bar", "foo": "bar",
}, },
}, },
},
fits: false, fits: false,
test: "missing labels", test: "missing labels",
}, },
{ {
pod: api.Pod{ pod: api.Pod{
Spec: api.PodSpec{
NodeSelector: map[string]string{ NodeSelector: map[string]string{
"foo": "bar", "foo": "bar",
}, },
}, },
},
labels: map[string]string{ labels: map[string]string{
"foo": "bar", "foo": "bar",
}, },
@ -307,10 +305,12 @@ func TestPodFitsSelector(t *testing.T) {
}, },
{ {
pod: api.Pod{ pod: api.Pod{
Spec: api.PodSpec{
NodeSelector: map[string]string{ NodeSelector: map[string]string{
"foo": "bar", "foo": "bar",
}, },
}, },
},
labels: map[string]string{ labels: map[string]string{
"foo": "bar", "foo": "bar",
"baz": "blah", "baz": "blah",
@ -320,11 +320,13 @@ func TestPodFitsSelector(t *testing.T) {
}, },
{ {
pod: api.Pod{ pod: api.Pod{
Spec: api.PodSpec{
NodeSelector: map[string]string{ NodeSelector: map[string]string{
"foo": "bar", "foo": "bar",
"baz": "blah", "baz": "blah",
}, },
}, },
},
labels: map[string]string{ labels: map[string]string{
"foo": "bar", "foo": "bar",
}, },

View File

@ -35,7 +35,7 @@ func calculateOccupancy(node api.Minion, pods []api.Pod) HostPriority {
totalCPU := 0 totalCPU := 0
totalMemory := 0 totalMemory := 0
for _, pod := range pods { for _, pod := range pods {
for _, container := range pod.DesiredState.Manifest.Containers { for _, container := range pod.Spec.Containers {
totalCPU += container.CPU totalCPU += container.CPU
totalMemory += container.Memory totalMemory += container.Memory
} }

View File

@ -46,29 +46,24 @@ func TestLeastRequested(t *testing.T) {
"bar": "foo", "bar": "foo",
"baz": "blah", "baz": "blah",
} }
machine1State := api.PodState{ machine1Status := api.PodStatus{
Host: "machine1", Host: "machine1",
} }
machine2State := api.PodState{ machine2Status := api.PodStatus{
Host: "machine2", Host: "machine2",
} }
cpuOnly := api.PodState{ cpuOnly := api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{CPU: 1000}, {CPU: 1000},
{CPU: 2000}, {CPU: 2000},
}, },
}, // Host: "machine1",
Host: "machine1",
} }
cpuAndMemory := api.PodState{ cpuAndMemory := api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{CPU: 1000, Memory: 2000}, {CPU: 1000, Memory: 2000},
{CPU: 2000, Memory: 3000}, {CPU: 2000, Memory: 3000},
}, },
},
Host: "machine2",
} }
tests := []struct { tests := []struct {
pod api.Pod pod api.Pod
@ -87,10 +82,10 @@ func TestLeastRequested(t *testing.T) {
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}},
test: "no resources requested", test: "no resources requested",
pods: []api.Pod{ pods: []api.Pod{
{DesiredState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}},
{DesiredState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
{DesiredState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
{DesiredState: machine2State, 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) */}}, expectedList: []HostPriority{{"machine1", 37 /* int(75% / 2) */}, {"machine2", 62 /* int( 75% + 50% / 2) */}},
test: "no resources requested", test: "no resources requested",
pods: []api.Pod{ pods: []api.Pod{
{DesiredState: cpuOnly}, {Spec: cpuOnly, Status: api.PodStatus{Host: "machine1"}},
{DesiredState: cpuAndMemory}, {Spec: cpuAndMemory, Status: api.PodStatus{Host: "machine2"}},
}, },
}, },
{ {
@ -107,8 +102,8 @@ func TestLeastRequested(t *testing.T) {
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}},
test: "zero minion resources", test: "zero minion resources",
pods: []api.Pod{ pods: []api.Pod{
{DesiredState: cpuOnly}, {Spec: cpuOnly},
{DesiredState: cpuAndMemory}, {Spec: cpuAndMemory},
}, },
}, },
} }

View File

@ -65,17 +65,15 @@ func newPod(host string, hostPorts ...int) api.Pod {
networkPorts = append(networkPorts, api.Port{HostPort: port}) networkPorts = append(networkPorts, api.Port{HostPort: port})
} }
return api.Pod{ return api.Pod{
CurrentState: api.PodState{ Status: api.PodStatus{
Host: host, Host: host,
}, },
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Ports: networkPorts, Ports: networkPorts,
}, },
}, },
}, },
},
} }
} }

View File

@ -39,7 +39,7 @@ func CalculateSpreadPriority(pod api.Pod, podLister PodLister, minionLister Mini
counts := map[string]int{} counts := map[string]int{}
for _, pod := range pods { for _, pod := range pods {
counts[pod.CurrentState.Host]++ counts[pod.Status.Host]++
} }
result := []HostPriority{} result := []HostPriority{}

View File

@ -32,10 +32,10 @@ func TestSpreadPriority(t *testing.T) {
"bar": "foo", "bar": "foo",
"baz": "blah", "baz": "blah",
} }
machine1State := api.PodState{ machine1Status := api.PodStatus{
Host: "machine1", Host: "machine1",
} }
machine2State := api.PodState{ machine2Status := api.PodStatus{
Host: "machine2", Host: "machine2",
} }
tests := []struct { tests := []struct {
@ -52,14 +52,14 @@ func TestSpreadPriority(t *testing.T) {
}, },
{ {
pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}},
pods: []api.Pod{{CurrentState: machine1State}}, pods: []api.Pod{{Status: machine1Status}},
nodes: []string{"machine1", "machine2"}, nodes: []string{"machine1", "machine2"},
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}},
test: "no labels", test: "no labels",
}, },
{ {
pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, 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"}, nodes: []string{"machine1", "machine2"},
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 0}},
test: "different labels", test: "different labels",
@ -67,8 +67,8 @@ func TestSpreadPriority(t *testing.T) {
{ {
pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}},
pods: []api.Pod{ pods: []api.Pod{
{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}},
{CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
}, },
nodes: []string{"machine1", "machine2"}, nodes: []string{"machine1", "machine2"},
expectedList: []HostPriority{{"machine1", 0}, {"machine2", 1}}, expectedList: []HostPriority{{"machine1", 0}, {"machine2", 1}},
@ -77,9 +77,9 @@ func TestSpreadPriority(t *testing.T) {
{ {
pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}},
pods: []api.Pod{ pods: []api.Pod{
{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}},
{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
{CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
}, },
nodes: []string{"machine1", "machine2"}, nodes: []string{"machine1", "machine2"},
expectedList: []HostPriority{{"machine1", 1}, {"machine2", 1}}, expectedList: []HostPriority{{"machine1", 1}, {"machine2", 1}},
@ -88,10 +88,10 @@ func TestSpreadPriority(t *testing.T) {
{ {
pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}}, pod: api.Pod{ObjectMeta: api.ObjectMeta{Labels: labels1}},
pods: []api.Pod{ pods: []api.Pod{
{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels2}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels2}},
{CurrentState: machine1State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine1Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
{CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
{CurrentState: machine2State, ObjectMeta: api.ObjectMeta{Labels: labels1}}, {Status: machine2Status, ObjectMeta: api.ObjectMeta{Labels: labels1}},
}, },
nodes: []string{"machine1", "machine2"}, nodes: []string{"machine1", "machine2"},
expectedList: []HostPriority{{"machine1", 1}, {"machine2", 2}}, expectedList: []HostPriority{{"machine1", 1}, {"machine2", 2}},

View File

@ -64,17 +64,18 @@ func (e *EndpointController) SyncServiceEndpoints() error {
continue continue
} }
endpoints := []string{} endpoints := []string{}
for _, pod := range pods.Items { for _, pod := range pods.Items {
port, err := findPort(&pod.DesiredState.Manifest, service.Spec.ContainerPort) port, err := findPort(&pod, service.Spec.ContainerPort)
if err != nil { if err != nil {
glog.Errorf("Failed to find port for service: %v, %v", service, err) glog.Errorf("Failed to find port for service: %v, %v", service, err)
continue continue
} }
if len(pod.CurrentState.PodIP) == 0 { if len(pod.Status.PodIP) == 0 {
glog.Errorf("Failed to find an IP for pod: %v", pod) glog.Errorf("Failed to find an IP for pod: %v", pod)
continue 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) currentEndpoints, err := e.client.Endpoints(service.Namespace).Get(service.Name)
if err != nil { 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. // 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 firstContainerPort := 0
if len(manifest.Containers[0].Ports) > 0 { if len(pod.Spec.Containers) > 0 && len(pod.Spec.Containers[0].Ports) > 0 {
firstContainerPort = manifest.Containers[0].Ports[0].ContainerPort firstContainerPort = pod.Spec.Containers[0].Ports[0].ContainerPort
} }
switch portName.Kind { switch portName.Kind {
@ -152,7 +153,7 @@ func findPort(manifest *api.ContainerManifest, portName util.IntOrString) (int,
break break
} }
name := portName.StrVal name := portName.StrVal
for _, container := range manifest.Containers { for _, container := range pod.Spec.Containers {
for _, port := range container.Ports { for _, port := range container.Ports {
if port.Name == name { if port.Name == name {
return port.ContainerPort, nil return port.ContainerPort, nil
@ -169,5 +170,5 @@ func findPort(manifest *api.ContainerManifest, portName util.IntOrString) (int,
return portName.IntVal, nil 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)
} }

View File

@ -36,8 +36,7 @@ func newPodList(count int) *api.PodList {
pods = append(pods, api.Pod{ pods = append(pods, api.Pod{
TypeMeta: api.TypeMeta{APIVersion: testapi.Version()}, TypeMeta: api.TypeMeta{APIVersion: testapi.Version()},
ObjectMeta: api.ObjectMeta{Name: fmt.Sprintf("pod%d", i)}, ObjectMeta: api.ObjectMeta{Name: fmt.Sprintf("pod%d", i)},
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Containers: []api.Container{ Containers: []api.Container{
{ {
Ports: []api.Port{ Ports: []api.Port{
@ -48,8 +47,7 @@ func newPodList(count int) *api.PodList {
}, },
}, },
}, },
}, Status: api.PodStatus{
CurrentState: api.PodState{
PodIP: "1.2.3.4", PodIP: "1.2.3.4",
}, },
}) })
@ -61,7 +59,8 @@ func newPodList(count int) *api.PodList {
} }
func TestFindPort(t *testing.T) { func TestFindPort(t *testing.T) {
manifest := api.ContainerManifest{ pod := api.Pod{
Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Ports: []api.Port{ Ports: []api.Port{
@ -78,78 +77,83 @@ func TestFindPort(t *testing.T) {
}, },
}, },
}, },
},
} }
emptyPortsManifest := api.ContainerManifest{
emptyPortsPod := api.Pod{
Spec: api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
Ports: []api.Port{}, Ports: []api.Port{},
}, },
}, },
},
} }
tests := []struct { tests := []struct {
manifest api.ContainerManifest pod api.Pod
portName util.IntOrString portName util.IntOrString
wport int wport int
werr bool werr bool
}{ }{
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrString, StrVal: "foo"}, util.IntOrString{Kind: util.IntstrString, StrVal: "foo"},
8080, 8080,
false, false,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrString, StrVal: "bar"}, util.IntOrString{Kind: util.IntstrString, StrVal: "bar"},
8000, 8000,
false, false,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrInt, IntVal: 8000}, util.IntOrString{Kind: util.IntstrInt, IntVal: 8000},
8000, 8000,
false, false,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrInt, IntVal: 7000}, util.IntOrString{Kind: util.IntstrInt, IntVal: 7000},
7000, 7000,
false, false,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrString, StrVal: "baz"}, util.IntOrString{Kind: util.IntstrString, StrVal: "baz"},
0, 0,
true, true,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrString, StrVal: ""}, util.IntOrString{Kind: util.IntstrString, StrVal: ""},
8080, 8080,
false, false,
}, },
{ {
manifest, pod,
util.IntOrString{Kind: util.IntstrInt, IntVal: 0}, util.IntOrString{Kind: util.IntstrInt, IntVal: 0},
8080, 8080,
false, false,
}, },
{ {
emptyPortsManifest, emptyPortsPod,
util.IntOrString{Kind: util.IntstrString, StrVal: ""}, util.IntOrString{Kind: util.IntstrString, StrVal: ""},
0, 0,
true, true,
}, },
{ {
emptyPortsManifest, emptyPortsPod,
util.IntOrString{Kind: util.IntstrInt, IntVal: 0}, util.IntOrString{Kind: util.IntstrInt, IntVal: 0},
0, 0,
true, true,
}, },
} }
for _, test := range tests { for _, test := range tests {
port, err := findPort(&test.manifest, test.portName) port, err := findPort(&test.pod, test.portName)
if port != test.wport { if port != test.wport {
t.Errorf("Expected port %d, Got %d", test.wport, port) t.Errorf("Expected port %d, Got %d", test.wport, port)
} }

View File

@ -192,7 +192,7 @@ func (factory *ConfigFactory) makeDefaultErrorFunc(backoff *podBackoff, podQueue
glog.Errorf("Error getting pod %v for retry: %v; abandoning", podID, err) glog.Errorf("Error getting pod %v for retry: %v; abandoning", podID, err)
return return
} }
if pod.DesiredState.Host == "" { if pod.Status.Host == "" {
podQueue.Add(pod.Name, pod) podQueue.Add(pod.Name, pod)
} }
}() }()

View File

@ -79,24 +79,22 @@ func TestClient(t *testing.T) {
// get a validation error // get a validation error
pod := &api.Pod{ pod := &api.Pod{
DesiredState: api.PodState{ Spec: api.PodSpec{
Manifest: api.ContainerManifest{
Version: "v1beta2",
Containers: []api.Container{ Containers: []api.Container{
{ {
Name: "test", Name: "test",
}, },
}, },
}, },
},
} }
got, err := client.Pods(ns).Create(pod) got, err := client.Pods(ns).Create(pod)
if err == nil { if err == nil {
t.Fatalf("unexpected non-error: %v", err) t.Fatalf("unexpected non-error: %v", got)
} }
// get a created pod // 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) got, err = client.Pods(ns).Create(pod)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -117,7 +115,7 @@ func TestClient(t *testing.T) {
if actual.Name != got.Name { if actual.Name != got.Name {
t.Errorf("expected pod %#v, got %#v", got, actual) 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) t.Errorf("expected pod to be unscheduled, got %#v", actual)
} }
} }