v1beta3 Pod refactor

pull/6/head
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)
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)

View File

@ -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",
},
}

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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},
},
},
},

View File

@ -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{

View File

@ -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)
}
}

View File

@ -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))

View File

@ -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)

View File

@ -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
}

View File

@ -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]).

View File

@ -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:

View File

@ -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
}

View File

@ -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)
}

View File

@ -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",
},
}

View File

@ -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

View File

@ -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.")
}
}

View File

@ -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{

View File

@ -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",
},
},
},

View File

@ -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 {

View File

@ -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,7 +515,13 @@ func TestPodStorageValidatesCreate(t *testing.T) {
registry: podRegistry,
}
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)
if c != nil {
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) {
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)
}
}

View File

@ -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

View File

@ -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{

View File

@ -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
}

View File

@ -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},
},
},
}

View File

@ -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,
},
},
},

View File

@ -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{}

View File

@ -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}},

View File

@ -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)
}

View File

@ -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)
}

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)
return
}
if pod.DesiredState.Host == "" {
if pod.Status.Host == "" {
podQueue.Add(pod.Name, pod)
}
}()

View File

@ -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)
}
}