Merge pull request #5502 from wojtek-t/completely_remove_bound_pods

Remove BoundPod type from source code
This commit is contained in:
Victor Marmol 2015-03-17 08:09:50 -07:00
commit 668e2dbcd8
19 changed files with 15 additions and 375 deletions

View File

@ -83,19 +83,19 @@ The Kubelet will have an interface that points to a `SecurityContextProvider`. T
```go ```go
type SecurityContextProvider interface { type SecurityContextProvider interface {
// ModifyContainerConfig is called before the Docker createContainer call. // ModifyContainerConfig is called before the Docker createContainer call.
// The security context provider can make changes to the Config with which // The security context provider can make changes to the Config with which
// the container is created. // the container is created.
// An error is returned if it's not possible to secure the container as // An error is returned if it's not possible to secure the container as
// requested with a security context. // requested with a security context.
ModifyContainerConfig(pod *api.BoundPod, container *api.Container, config *docker.Config) error ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config) error
// ModifyHostConfig is called before the Docker runContainer call. // ModifyHostConfig is called before the Docker runContainer call.
// The security context provider can make changes to the HostConfig, affecting // The security context provider can make changes to the HostConfig, affecting
// security options, whether the container is privileged, volume binds, etc. // security options, whether the container is privileged, volume binds, etc.
// An error is returned if it's not possible to secure the container as requested // An error is returned if it's not possible to secure the container as requested
// with a security context. // with a security context.
ModifyHostConfig(pod *api.BoundPod, container *api.Container, hostConfig *docker.HostConfig) ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig)
} }
``` ```

View File

@ -28,7 +28,7 @@ To learn how to query, fitler etc. using Kibana you might like to look at this [
You can check to see if any logs are being ingested into Elasticsearch by curling against its URL. You will need to provide the username and password that was generated when your cluster was created. This can be found in the `kubernetes_auth` file for your cluster. You can check to see if any logs are being ingested into Elasticsearch by curling against its URL. You will need to provide the username and password that was generated when your cluster was created. This can be found in the `kubernetes_auth` file for your cluster.
``` ```
curl -k -u admin:Drt3KdRGnoQL6TQM https://130.211.152.93/api/v1beta1/proxy/services/elasticsearch-logging/_search?size=10 curl -k -u admin:Drt3KdRGnoQL6TQM https://130.211.152.93/api/v1beta1/proxy/services/elasticsearch-logging/_search?size=10
{"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":3705,"max_score":1.0,"hits":[{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdh","_score":1.0,"_source":{"message":"I0108 18:30:47.694725 4927 server.go:313] GET /healthz: (9.249us) 200","tag":"kubelet","@timestamp":"2015-01-08T18:30:47+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdm","_score":1.0,"_source":{"message":"E0108 18:30:52.299372 4927 metadata.go:109] while reading 'google-dockercfg' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg","tag":"kubelet","@timestamp":"2015-01-08T18:30:52+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdr","_score":1.0,"_source":{"message":"I0108 18:30:52.317636 4927 docker.go:214] Pulling image kubernetes/kube2sky without credentials","tag":"kubelet","@timestamp":"2015-01-08T18:30:52+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdw","_score":1.0,"_source":{"message":"I0108 18:30:54.500174 4927 event.go:92] Event(api.ObjectReference{Kind:\"BoundPod\", Namespace:\"default\", Name:\"67cfcb1f-9764-11e4-898c-42010af03582\", UID:\"67cfcb1f-9764-11e4-898c-42010af03582\", APIVersion:\"v1beta1\", ResourceVersion:\"\", FieldPath:\"spec.containers{kube2sky}\"}): status: 'waiting', reason: 'created' Created with docker id ff24ec6eb3b10d1163a2bcb7c63ccef78e6e3e7a1185eba3fe430f6b3d871eb5","tag":"kubelet","@timestamp":"2015-01-08T18:30:54+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpd1","_score":1.0,"_source":{"message":"goroutine 114 [running]:","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpd6","_score":1.0,"_source":{"message":"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet.(*Server).error(0xc2080e0060, 0x7fe0ba496840, 0xc208278840, 0x7fe0ba4881b0, 0xc20822daa0)","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8DurpeB","_score":1.0,"_source":{"message":"\t/go/src/github.com/GoogleCloudPlatform/kubernetes/_output/dockerized/go/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server.go:94 +0x44","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeJ","_score":1.0,"_source":{"message":"goroutine 114 [running]:","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeO","_score":1.0,"_source":{"message":"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet.(*Server).error(0xc2080e0060, 0x7fe0ba496840, 0xc208278a80, 0x7fe0ba4881b0, 0xc20822df00)","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeT","_score":1.0,"_source":{"message":"\t/go/src/github.com/GoogleCloudPlatform/kubernetes/_output/dockerized/go/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server.go:240 +0x45","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}}]}} {"took":7,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":3705,"max_score":1.0,"hits":[{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdh","_score":1.0,"_source":{"message":"I0108 18:30:47.694725 4927 server.go:313] GET /healthz: (9.249us) 200","tag":"kubelet","@timestamp":"2015-01-08T18:30:47+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdm","_score":1.0,"_source":{"message":"E0108 18:30:52.299372 4927 metadata.go:109] while reading 'google-dockercfg' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg","tag":"kubelet","@timestamp":"2015-01-08T18:30:52+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdr","_score":1.0,"_source":{"message":"I0108 18:30:52.317636 4927 docker.go:214] Pulling image kubernetes/kube2sky without credentials","tag":"kubelet","@timestamp":"2015-01-08T18:30:52+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpdw","_score":1.0,"_source":{"message":"I0108 18:30:54.500174 4927 event.go:92] Event(api.ObjectReference{Kind:\"Pod\", Namespace:\"default\", Name:\"67cfcb1f-9764-11e4-898c-42010af03582\", UID:\"67cfcb1f-9764-11e4-898c-42010af03582\", APIVersion:\"v1beta1\", ResourceVersion:\"\", FieldPath:\"spec.containers{kube2sky}\"}): status: 'waiting', reason: 'created' Created with docker id ff24ec6eb3b10d1163a2bcb7c63ccef78e6e3e7a1185eba3fe430f6b3d871eb5","tag":"kubelet","@timestamp":"2015-01-08T18:30:54+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpd1","_score":1.0,"_source":{"message":"goroutine 114 [running]:","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8Durpd6","_score":1.0,"_source":{"message":"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet.(*Server).error(0xc2080e0060, 0x7fe0ba496840, 0xc208278840, 0x7fe0ba4881b0, 0xc20822daa0)","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRRanI4L8DurpeB","_score":1.0,"_source":{"message":"\t/go/src/github.com/GoogleCloudPlatform/kubernetes/_output/dockerized/go/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server.go:94 +0x44","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeJ","_score":1.0,"_source":{"message":"goroutine 114 [running]:","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeO","_score":1.0,"_source":{"message":"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet.(*Server).error(0xc2080e0060, 0x7fe0ba496840, 0xc208278a80, 0x7fe0ba4881b0, 0xc20822df00)","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}},{"_index":"logstash-2015.01.08","_type":"fluentd","_id":"AUrK0hRSanI4L8DurpeT","_score":1.0,"_source":{"message":"\t/go/src/github.com/GoogleCloudPlatform/kubernetes/_output/dockerized/go/src/github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/server.go:240 +0x45","tag":"kubelet","@timestamp":"2015-01-08T18:30:56+00:00"}}]}}
``` ```
A [demonstration](../cluster/addons/fluentd-elasticsearch/logging-demo/README.md) of two synthetic logging sources can be used A [demonstration](../cluster/addons/fluentd-elasticsearch/logging-demo/README.md) of two synthetic logging sources can be used
to check that logging is working correctly. to check that logging is working correctly.

View File

@ -84,20 +84,6 @@ func init() {
return nil return nil
}, },
// Convert Pod to BoundPod
func(in *Pod, out *BoundPod, s conversion.Scope) error {
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
// metadata
out.UID = in.UID
out.Name = in.Name
out.Namespace = in.Namespace
out.CreationTimestamp = in.CreationTimestamp
return nil
},
// Conversion between Manifest and PodSpec // Conversion between Manifest and PodSpec
func(in *PodSpec, out *ContainerManifest, s conversion.Scope) error { func(in *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 {

View File

@ -43,7 +43,6 @@ func init() {
&EventList{}, &EventList{},
&ContainerManifest{}, &ContainerManifest{},
&ContainerManifestList{}, &ContainerManifestList{},
&BoundPod{},
&List{}, &List{},
&LimitRange{}, &LimitRange{},
&LimitRangeList{}, &LimitRangeList{},
@ -77,7 +76,6 @@ func (*Event) IsAnAPIObject() {}
func (*EventList) IsAnAPIObject() {} func (*EventList) IsAnAPIObject() {}
func (*ContainerManifest) IsAnAPIObject() {} func (*ContainerManifest) IsAnAPIObject() {}
func (*ContainerManifestList) IsAnAPIObject() {} func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {} func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {} func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {} func (*LimitRangeList) IsAnAPIObject() {}

View File

@ -1270,19 +1270,6 @@ type ContainerManifestList struct {
Items []ContainerManifest `json:"items"` Items []ContainerManifest `json:"items"`
} }
// BoundPod is a collection of containers that should be run on a host. A BoundPod
// defines how a Pod may change after a Binding is created. A Pod is a request to
// execute a pod, whereas a BoundPod is the specification that would be run on a server.
//
// TODO(wojtek-t): Get rid of this type.
type BoundPod struct {
TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty"`
// Spec defines the behavior of a pod.
Spec PodSpec `json:"spec,omitempty"`
}
// List holds a list of objects, which may not be known by the server. // List holds a list of objects, which may not be known by the server.
type List struct { type List struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`

View File

@ -448,18 +448,6 @@ 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
},
// Converts internal Container to v1beta1.Container. // Converts internal Container to v1beta1.Container.
// Fields 'CPU' and 'Memory' are not present in the internal Container object. // Fields 'CPU' and 'Memory' are not present in the internal Container object.
// Hence the need for a custom conversion function. // Hence the need for a custom conversion function.

View File

@ -51,48 +51,6 @@ func TestSetDefaultService(t *testing.T) {
} }
} }
func TestSetDefaulPodSpec(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Volumes = []current.Volume{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
if bp2.Spec.DNSPolicy != current.DNSClusterFirst {
t.Errorf("Expected default dns policy :%s, got: %s", current.DNSClusterFirst, bp2.Spec.DNSPolicy)
}
policy := bp2.Spec.RestartPolicy
if policy.Never != nil || policy.OnFailure != nil || policy.Always == nil {
t.Errorf("Expected only policy.Always is set, got: %s", policy)
}
vsource := bp2.Spec.Volumes[0].Source
if vsource.EmptyDir == nil {
t.Errorf("Expected non-empty volume is set, got: %s", vsource.EmptyDir)
}
}
func TestSetDefaultContainer(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Containers = []current.Container{{}}
bp.Spec.Containers[0].Ports = []current.ContainerPort{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
container := bp2.Spec.Containers[0]
if container.TerminationMessagePath != current.TerminationMessagePathDefault {
t.Errorf("Expected termination message path: %s, got: %s",
current.TerminationMessagePathDefault, container.TerminationMessagePath)
}
if container.ImagePullPolicy != current.PullIfNotPresent {
t.Errorf("Expected image pull policy: %s, got: %s",
current.PullIfNotPresent, container.ImagePullPolicy)
}
if container.Ports[0].Protocol != current.ProtocolTCP {
t.Errorf("Expected protocol: %s, got: %s",
current.ProtocolTCP, container.Ports[0].Protocol)
}
}
func TestSetDefaultSecret(t *testing.T) { func TestSetDefaultSecret(t *testing.T) {
s := &current.Secret{} s := &current.Secret{}
obj2 := roundTrip(t, runtime.Object(s)) obj2 := roundTrip(t, runtime.Object(s))

View File

@ -50,8 +50,6 @@ func init() {
&EventList{}, &EventList{},
&ContainerManifest{}, &ContainerManifest{},
&ContainerManifestList{}, &ContainerManifestList{},
&BoundPod{},
&BoundPods{},
&List{}, &List{},
&LimitRange{}, &LimitRange{},
&LimitRangeList{}, &LimitRangeList{},
@ -85,8 +83,6 @@ func (*Event) IsAnAPIObject() {}
func (*EventList) IsAnAPIObject() {} func (*EventList) IsAnAPIObject() {}
func (*ContainerManifest) IsAnAPIObject() {} func (*ContainerManifest) IsAnAPIObject() {}
func (*ContainerManifestList) IsAnAPIObject() {} func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {} func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {} func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {} func (*LimitRangeList) IsAnAPIObject() {}

View File

@ -1060,28 +1060,6 @@ type PodSpec struct {
Host string `json:"host,omitempty" description:"host requested for this pod"` Host string `json:"host,omitempty" description:"host requested for this pod"`
} }
// BoundPod is a collection of containers that should be run on a host. A BoundPod
// defines how a Pod may change after a Binding is created. A Pod is a request to
// execute a pod, whereas a BoundPod is the specification that would be run on a server.
type BoundPod struct {
TypeMeta `json:",inline"`
// Spec defines the behavior of a pod.
Spec PodSpec `json:"spec,omitempty" description:"specification of the desired state of containers and volumes comprising the pod"`
}
// BoundPods is a list of Pods bound to a common server. The resource version of
// the pod list is guaranteed to only change when the list of bound pods changes.
type BoundPods struct {
TypeMeta `json:",inline"`
// Host is the name of a node that these pods were bound to.
Host string `json:"host" description:"name of a node that these pods were bound to"`
// Items is the list of all pods bound to a given host.
Items []Pod `json:"items" description:"list of all pods bound to a given host"`
}
// List holds a list of objects, which may not be known by the server. // List holds a list of objects, which may not be known by the server.
type List struct { type List struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`

View File

@ -51,48 +51,6 @@ func TestSetDefaultService(t *testing.T) {
} }
} }
func TestSetDefaulPodSpec(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Volumes = []current.Volume{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
if bp2.Spec.DNSPolicy != current.DNSClusterFirst {
t.Errorf("Expected default dns policy :%s, got: %s", current.DNSClusterFirst, bp2.Spec.DNSPolicy)
}
policy := bp2.Spec.RestartPolicy
if policy.Never != nil || policy.OnFailure != nil || policy.Always == nil {
t.Errorf("Expected only policy.Always is set, got: %s", policy)
}
vsource := bp2.Spec.Volumes[0].Source
if vsource.EmptyDir == nil {
t.Errorf("Expected non-empty volume is set, got: %s", vsource.EmptyDir)
}
}
func TestSetDefaultContainer(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Containers = []current.Container{{}}
bp.Spec.Containers[0].Ports = []current.ContainerPort{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
container := bp2.Spec.Containers[0]
if container.TerminationMessagePath != current.TerminationMessagePathDefault {
t.Errorf("Expected termination message path: %s, got: %s",
current.TerminationMessagePathDefault, container.TerminationMessagePath)
}
if container.ImagePullPolicy != current.PullIfNotPresent {
t.Errorf("Expected image pull policy: %s, got: %s",
current.PullIfNotPresent, container.ImagePullPolicy)
}
if container.Ports[0].Protocol != current.ProtocolTCP {
t.Errorf("Expected protocol: %s, got: %s",
current.ProtocolTCP, container.Ports[0].Protocol)
}
}
func TestSetDefaultSecret(t *testing.T) { func TestSetDefaultSecret(t *testing.T) {
s := &current.Secret{} s := &current.Secret{}
obj2 := roundTrip(t, runtime.Object(s)) obj2 := roundTrip(t, runtime.Object(s))

View File

@ -50,8 +50,6 @@ func init() {
&EventList{}, &EventList{},
&ContainerManifest{}, &ContainerManifest{},
&ContainerManifestList{}, &ContainerManifestList{},
&BoundPod{},
&BoundPods{},
&List{}, &List{},
&LimitRange{}, &LimitRange{},
&LimitRangeList{}, &LimitRangeList{},
@ -85,8 +83,6 @@ func (*Event) IsAnAPIObject() {}
func (*EventList) IsAnAPIObject() {} func (*EventList) IsAnAPIObject() {}
func (*ContainerManifest) IsAnAPIObject() {} func (*ContainerManifest) IsAnAPIObject() {}
func (*ContainerManifestList) IsAnAPIObject() {} func (*ContainerManifestList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*List) IsAnAPIObject() {} func (*List) IsAnAPIObject() {}
func (*LimitRange) IsAnAPIObject() {} func (*LimitRange) IsAnAPIObject() {}
func (*LimitRangeList) IsAnAPIObject() {} func (*LimitRangeList) IsAnAPIObject() {}

View File

@ -1065,7 +1065,7 @@ type EventList struct {
// ContainerManifest corresponds to the Container Manifest format, documented at: // ContainerManifest corresponds to the Container Manifest format, documented at:
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest // https://developers.google.com/compute/docs/containers/container_vms#container_manifest
// This is used as the representation of Kubernetes workloads. // This is used as the representation of Kubernetes workloads.
// DEPRECATED: Replaced with BoundPod // DEPRECATED: Replaced with Pod
type ContainerManifest struct { type ContainerManifest struct {
// Required: This must be a supported version string, such as "v1beta1". // Required: This must be a supported version string, such as "v1beta1".
Version string `json:"version" description:"manifest version; must be v1beta1"` Version string `json:"version" description:"manifest version; must be v1beta1"`
@ -1084,7 +1084,7 @@ type ContainerManifest struct {
} }
// ContainerManifestList is used to communicate container manifests to kubelet. // ContainerManifestList is used to communicate container manifests to kubelet.
// DEPRECATED: Replaced with BoundPods // DEPRECATED: Replaced with PodList
type ContainerManifestList struct { type ContainerManifestList struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`
Items []ContainerManifest `json:"items" description:"list of pod container manifests"` Items []ContainerManifest `json:"items" description:"list of pod container manifests"`
@ -1122,28 +1122,6 @@ type PodSpec struct {
Host string `json:"host,omitempty" description:"host requested for this pod"` Host string `json:"host,omitempty" description:"host requested for this pod"`
} }
// BoundPod is a collection of containers that should be run on a host. A BoundPod
// defines how a Pod may change after a Binding is created. A Pod is a request to
// execute a pod, whereas a BoundPod is the specification that would be run on a server.
type BoundPod struct {
TypeMeta `json:",inline"`
// Spec defines the behavior of a pod.
Spec PodSpec `json:"spec,omitempty" description:"specification of the desired state of containers and volumes comprising the pod"`
}
// BoundPods is a list of Pods bound to a common server. The resource version of
// the pod list is guaranteed to only change when the list of bound pods changes.
type BoundPods struct {
TypeMeta `json:",inline"`
// Host is the name of a node that these pods were bound to.
Host string `json:"host" description:"name of a node that these pods were bound to"`
// Items is the list of all pods bound to a given host.
Items []Pod `json:"items" description:"list of all pods bound to a given host"`
}
// List holds a list of objects, which may not be known by the server. // List holds a list of objects, which may not be known by the server.
type List struct { type List struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`

View File

@ -52,48 +52,6 @@ func TestSetDefaultService(t *testing.T) {
} }
} }
func TestSetDefaulPodSpec(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Volumes = []current.Volume{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
if bp2.Spec.DNSPolicy != current.DNSClusterFirst {
t.Errorf("Expected default dns policy :%s, got: %s", current.DNSClusterFirst, bp2.Spec.DNSPolicy)
}
policy := bp2.Spec.RestartPolicy
if policy != current.RestartPolicyAlways {
t.Errorf("Expected only policy.Always is set, got: %s", policy)
}
vsource := bp2.Spec.Volumes[0].VolumeSource
if vsource.EmptyDir == nil {
t.Errorf("Expected non-empty volume is set, got: %s", vsource.EmptyDir)
}
}
func TestSetDefaultContainer(t *testing.T) {
bp := &current.BoundPod{}
bp.Spec.Containers = []current.Container{{}}
bp.Spec.Containers[0].Ports = []current.ContainerPort{{}}
obj2 := roundTrip(t, runtime.Object(bp))
bp2 := obj2.(*current.BoundPod)
container := bp2.Spec.Containers[0]
if container.TerminationMessagePath != current.TerminationMessagePathDefault {
t.Errorf("Expected termination message path: %s, got: %s",
current.TerminationMessagePathDefault, container.TerminationMessagePath)
}
if container.ImagePullPolicy != current.PullIfNotPresent {
t.Errorf("Expected image pull policy: %s, got: %s",
current.PullIfNotPresent, container.ImagePullPolicy)
}
if container.Ports[0].Protocol != current.ProtocolTCP {
t.Errorf("Expected protocol: %s, got: %s",
current.ProtocolTCP, container.Ports[0].Protocol)
}
}
func TestSetDefaultSecret(t *testing.T) { func TestSetDefaultSecret(t *testing.T) {
s := &current.Secret{} s := &current.Secret{}
obj2 := roundTrip(t, runtime.Object(s)) obj2 := roundTrip(t, runtime.Object(s))

View File

@ -31,8 +31,6 @@ func init() {
&PodStatusResult{}, &PodStatusResult{},
&PodTemplate{}, &PodTemplate{},
&PodTemplateList{}, &PodTemplateList{},
&BoundPod{},
&BoundPods{},
&ReplicationController{}, &ReplicationController{},
&ReplicationControllerList{}, &ReplicationControllerList{},
&Service{}, &Service{},
@ -66,8 +64,6 @@ func (*PodList) IsAnAPIObject() {}
func (*PodStatusResult) IsAnAPIObject() {} func (*PodStatusResult) IsAnAPIObject() {}
func (*PodTemplate) IsAnAPIObject() {} func (*PodTemplate) IsAnAPIObject() {}
func (*PodTemplateList) IsAnAPIObject() {} func (*PodTemplateList) IsAnAPIObject() {}
func (*BoundPod) IsAnAPIObject() {}
func (*BoundPods) IsAnAPIObject() {}
func (*ReplicationController) IsAnAPIObject() {} func (*ReplicationController) IsAnAPIObject() {}
func (*ReplicationControllerList) IsAnAPIObject() {} func (*ReplicationControllerList) IsAnAPIObject() {}
func (*Service) IsAnAPIObject() {} func (*Service) IsAnAPIObject() {}

View File

@ -597,8 +597,7 @@ type PodStatusResult struct {
} }
// Pod is a collection of containers that can run on a host. This resource is created // Pod is a collection of containers that can run on a host. This resource is created
// by clients and scheduled onto hosts. BoundPod represents the state of this resource // by clients and scheduled onto hosts.
// to hosts.
type Pod struct { type Pod struct {
TypeMeta `json:",inline"` TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#metadata"` ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#metadata"`
@ -645,30 +644,6 @@ type PodTemplateList struct {
Items []PodTemplate `json:"items" description:"list of pod templates"` Items []PodTemplate `json:"items" description:"list of pod templates"`
} }
// BoundPod is a collection of containers that should be run on a host. A BoundPod
// defines how a Pod may change after a Binding is created. A Pod is a request to
// execute a pod, whereas a BoundPod is the specification that would be run on a server.
type BoundPod struct {
TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#metadata"`
// Spec defines the behavior of a pod.
Spec PodSpec `json:"spec,omitempty" description:"specification of the desired behavior of the pod; https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#spec-and-status"`
}
// BoundPods is a list of Pods bound to a common server. The resource version of
// the pod list is guaranteed to only change when the list of bound pods changes.
type BoundPods struct {
TypeMeta `json:",inline"`
ObjectMeta `json:"metadata,omitempty" description:"standard object metadata; see https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/api-conventions.md#metadata"`
// Host is the name of a node that these pods were bound to.
Host string `json:"host" description:"name of a node that these pods were bound to"`
// Items is the list of all pods bound to a given host.
Items []Pod `json:"items" description:"list of all pods bound to a given host"`
}
// ReplicationControllerSpec is the specification of a replication controller. // ReplicationControllerSpec is the specification of a replication controller.
type ReplicationControllerSpec struct { type ReplicationControllerSpec struct {
// Replicas is the number of desired replicas. // Replicas is the number of desired replicas.

View File

@ -813,26 +813,6 @@ func ValidateReadOnlyPersistentDisks(volumes []api.Volume) errs.ValidationErrorL
return allErrs return allErrs
} }
// ValidateBoundPod tests if required fields on a bound pod are set.
// TODO: to be removed.
func ValidateBoundPod(pod *api.BoundPod) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{}
if len(pod.Name) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("name", pod.Name))
} else {
if ok, qualifier := nameIsDNSSubdomain(pod.Name, false); !ok {
allErrs = append(allErrs, errs.NewFieldInvalid("name", pod.Name, qualifier))
}
}
if len(pod.Namespace) == 0 {
allErrs = append(allErrs, errs.NewFieldRequired("namespace", pod.Namespace))
} else if !util.IsDNSSubdomain(pod.Namespace) {
allErrs = append(allErrs, errs.NewFieldInvalid("namespace", pod.Namespace, dnsSubdomainErrorMsg))
}
allErrs = append(allErrs, ValidatePodSpec(&pod.Spec).Prefix("spec")...)
return allErrs
}
// ValidateMinion tests if required fields in the node are set. // ValidateMinion tests if required fields in the node are set.
func ValidateMinion(node *api.Node) errs.ValidationErrorList { func ValidateMinion(node *api.Node) errs.ValidationErrorList {
allErrs := errs.ValidationErrorList{} allErrs := errs.ValidationErrorList{}

View File

@ -1027,98 +1027,6 @@ func TestValidatePodUpdate(t *testing.T) {
} }
} }
func TestValidateBoundPods(t *testing.T) {
successCases := []api.BoundPod{
{ // Mostly empty.
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
{ // Basic fields.
ObjectMeta: api.ObjectMeta{Name: "123", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
{ // Just about everything.
ObjectMeta: api.ObjectMeta{Name: "abc.123.do-re-mi", Namespace: "ns"},
Spec: api.PodSpec{
Volumes: []api.Volume{
{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}},
},
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
NodeSelector: map[string]string{
"key": "value",
},
Host: "foobar",
},
},
}
for _, pod := range successCases {
if errs := ValidateBoundPod(&pod); len(errs) != 0 {
t.Errorf("expected success: %v", errs)
}
}
errorCases := map[string]api.Pod{
"zero-length name": {
ObjectMeta: api.ObjectMeta{Name: "", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
"bad namespace": {
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: ""},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
"bad spec": {
ObjectMeta: api.ObjectMeta{Name: "abc", Namespace: "ns"},
Spec: api.PodSpec{
Containers: []api.Container{{Name: "name", ImagePullPolicy: "IfNotPresent"}},
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
"name > 253 characters": {
ObjectMeta: api.ObjectMeta{Name: strings.Repeat("a", 254), Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
"name not a DNS subdomain": {
ObjectMeta: api.ObjectMeta{Name: "a..b.c", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
"name with underscore": {
ObjectMeta: api.ObjectMeta{Name: "a_b_c", Namespace: "ns"},
Spec: api.PodSpec{
RestartPolicy: api.RestartPolicyAlways,
DNSPolicy: api.DNSClusterFirst,
},
},
}
for k, v := range errorCases {
if errs := ValidatePod(&v); len(errs) != 1 {
t.Errorf("expected one failure for %s; got %d: %s", k, len(errs), errs)
}
}
}
func TestValidateService(t *testing.T) { func TestValidateService(t *testing.T) {
testCases := []struct { testCases := []struct {
name string name string

View File

@ -29,7 +29,7 @@ func TestAddOrUpdateEventNoExisting(t *testing.T) {
Reason: "my reasons are many", Reason: "my reasons are many",
Message: "my message is love", Message: "my message is love",
InvolvedObject: api.ObjectReference{ InvolvedObject: api.ObjectReference{
Kind: "BoundPod", Kind: "Pod",
Name: "awesome.name", Name: "awesome.name",
Namespace: "betterNamespace", Namespace: "betterNamespace",
UID: "C934D34AFB20242", UID: "C934D34AFB20242",
@ -143,7 +143,7 @@ func TestGetEventExisting(t *testing.T) {
Reason: "do I exist", Reason: "do I exist",
Message: "I do, oh my", Message: "I do, oh my",
InvolvedObject: api.ObjectReference{ InvolvedObject: api.ObjectReference{
Kind: "BoundPod", Kind: "Pod",
Name: "clever.name.here", Name: "clever.name.here",
Namespace: "spaceOfName", Namespace: "spaceOfName",
UID: "D933D32AFB2A238", UID: "D933D32AFB2A238",

View File

@ -224,7 +224,7 @@ func (d *PodDescriber) Describe(namespace, name string) (string, error) {
if ref, err := api.GetReference(pod); err != nil { if ref, err := api.GetReference(pod); err != nil {
glog.Errorf("Unable to construct reference to '%#v': %v", pod, err) glog.Errorf("Unable to construct reference to '%#v': %v", pod, err)
} else { } else {
ref.Kind = "" // Find BoundPod objects, too! ref.Kind = ""
events, _ = d.Events(namespace).Search(ref) events, _ = d.Events(namespace).Search(ref)
} }