mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Merge pull request #3478 from thockin/uid_type
Use a strong type for UID fields
This commit is contained in:
commit
8a764c02d5
@ -312,7 +312,7 @@ func TestKubeletSendsEvent(c *client.Client) bool {
|
|||||||
labels.Everything(),
|
labels.Everything(),
|
||||||
labels.Set{
|
labels.Set{
|
||||||
"involvedObject.kind": "Pod",
|
"involvedObject.kind": "Pod",
|
||||||
"involvedObject.uid": podWithUid.UID,
|
"involvedObject.uid": string(podWithUid.UID),
|
||||||
"involvedObject.namespace": api.NamespaceDefault,
|
"involvedObject.namespace": api.NamespaceDefault,
|
||||||
"source": "scheduler",
|
"source": "scheduler",
|
||||||
}.AsSelector(),
|
}.AsSelector(),
|
||||||
@ -331,7 +331,7 @@ func TestKubeletSendsEvent(c *client.Client) bool {
|
|||||||
events, err = c.Events(api.NamespaceDefault).List(
|
events, err = c.Events(api.NamespaceDefault).List(
|
||||||
labels.Everything(),
|
labels.Everything(),
|
||||||
labels.Set{
|
labels.Set{
|
||||||
"involvedObject.uid": podWithUid.UID,
|
"involvedObject.uid": string(podWithUid.UID),
|
||||||
"involvedObject.kind": "BoundPod",
|
"involvedObject.kind": "BoundPod",
|
||||||
"involvedObject.namespace": api.NamespaceDefault,
|
"involvedObject.namespace": api.NamespaceDefault,
|
||||||
"source": "kubelet",
|
"source": "kubelet",
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
|
// FillObjectMetaSystemFields populates fields that are managed by the system on ObjectMeta.
|
||||||
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
|
func FillObjectMetaSystemFields(ctx Context, meta *ObjectMeta) {
|
||||||
meta.CreationTimestamp = util.Now()
|
meta.CreationTimestamp = util.Now()
|
||||||
meta.UID = util.NewUUID().String()
|
meta.UID = util.NewUUID()
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
|
// HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
|
||||||
|
@ -18,6 +18,7 @@ package meta
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
||||||
@ -36,8 +37,8 @@ type Interface interface {
|
|||||||
SetNamespace(namespace string)
|
SetNamespace(namespace string)
|
||||||
Name() string
|
Name() string
|
||||||
SetName(name string)
|
SetName(name string)
|
||||||
UID() string
|
UID() util.UID
|
||||||
SetUID(uid string)
|
SetUID(uid util.UID)
|
||||||
APIVersion() string
|
APIVersion() string
|
||||||
SetAPIVersion(version string)
|
SetAPIVersion(version string)
|
||||||
Kind() string
|
Kind() string
|
||||||
@ -71,8 +72,8 @@ type MetadataAccessor interface {
|
|||||||
Name(obj runtime.Object) (string, error)
|
Name(obj runtime.Object) (string, error)
|
||||||
SetName(obj runtime.Object, name string) error
|
SetName(obj runtime.Object, name string) error
|
||||||
|
|
||||||
UID(obj runtime.Object) (string, error)
|
UID(obj runtime.Object) (util.UID, error)
|
||||||
SetUID(obj runtime.Object, uid string) error
|
SetUID(obj runtime.Object, uid util.UID) error
|
||||||
|
|
||||||
SelfLink(obj runtime.Object) (string, error)
|
SelfLink(obj runtime.Object) (string, error)
|
||||||
SetSelfLink(obj runtime.Object, selfLink string) error
|
SetSelfLink(obj runtime.Object, selfLink string) error
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Accessor takes an arbitary object pointer and returns meta.Interface.
|
// Accessor takes an arbitary object pointer and returns meta.Interface.
|
||||||
@ -151,7 +152,7 @@ func (resourceAccessor) SetName(obj runtime.Object, name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resourceAccessor) UID(obj runtime.Object) (string, error) {
|
func (resourceAccessor) UID(obj runtime.Object) (util.UID, error) {
|
||||||
accessor, err := Accessor(obj)
|
accessor, err := Accessor(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -159,7 +160,7 @@ func (resourceAccessor) UID(obj runtime.Object) (string, error) {
|
|||||||
return accessor.UID(), nil
|
return accessor.UID(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resourceAccessor) SetUID(obj runtime.Object, uid string) error {
|
func (resourceAccessor) SetUID(obj runtime.Object, uid util.UID) error {
|
||||||
accessor, err := Accessor(obj)
|
accessor, err := Accessor(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -241,7 +242,7 @@ func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) e
|
|||||||
type genericAccessor struct {
|
type genericAccessor struct {
|
||||||
namespace *string
|
namespace *string
|
||||||
name *string
|
name *string
|
||||||
uid *string
|
uid *util.UID
|
||||||
apiVersion *string
|
apiVersion *string
|
||||||
kind *string
|
kind *string
|
||||||
resourceVersion *string
|
resourceVersion *string
|
||||||
@ -278,14 +279,14 @@ func (a genericAccessor) SetName(name string) {
|
|||||||
*a.name = name
|
*a.name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a genericAccessor) UID() string {
|
func (a genericAccessor) UID() util.UID {
|
||||||
if a.uid == nil {
|
if a.uid == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return *a.uid
|
return *a.uid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a genericAccessor) SetUID(uid string) {
|
func (a genericAccessor) SetUID(uid util.UID) {
|
||||||
if a.uid == nil {
|
if a.uid == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func TestGenericTypeMeta(t *testing.T) {
|
|||||||
if e, a := "foo", accessor.Name(); e != a {
|
if e, a := "foo", accessor.Name(); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "uid", accessor.UID(); e != a {
|
if e, a := "uid", string(accessor.UID()); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "a", accessor.APIVersion(); e != a {
|
if e, a := "a", accessor.APIVersion(); e != a {
|
||||||
@ -162,7 +162,7 @@ func TestGenericTypeMetaAccessor(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error: %v", err)
|
t.Errorf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
if e, a := "uid", uid; e != a {
|
if e, a := "uid", string(uid); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
apiVersion, err := accessor.APIVersion(j)
|
apiVersion, err := accessor.APIVersion(j)
|
||||||
@ -311,7 +311,7 @@ func TestGenericObjectMeta(t *testing.T) {
|
|||||||
if e, a := "foo", accessor.Name(); e != a {
|
if e, a := "foo", accessor.Name(); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "uid", accessor.UID(); e != a {
|
if e, a := "uid", string(accessor.UID()); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "a", accessor.APIVersion(); e != a {
|
if e, a := "a", accessor.APIVersion(); e != a {
|
||||||
@ -403,7 +403,7 @@ func TestGenericListMeta(t *testing.T) {
|
|||||||
if e, a := "", accessor.Name(); e != a {
|
if e, a := "", accessor.Name(); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "", accessor.UID(); e != a {
|
if e, a := "", string(accessor.UID()); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("expected %v, got %v", e, a)
|
||||||
}
|
}
|
||||||
if e, a := "a", accessor.APIVersion(); e != a {
|
if e, a := "a", accessor.APIVersion(); e != a {
|
||||||
|
@ -93,7 +93,7 @@ type ObjectMeta struct {
|
|||||||
// UID is the unique in time and space value for this object. It is typically generated by
|
// UID is the unique in time and space value for this object. It is typically generated by
|
||||||
// the server on successful creation of a resource and is not allowed to change on PUT
|
// the server on successful creation of a resource and is not allowed to change on PUT
|
||||||
// operations.
|
// operations.
|
||||||
UID string `json:"uid,omitempty"`
|
UID util.UID `json:"uid,omitempty"`
|
||||||
|
|
||||||
// An opaque value that represents the version of this resource. May be used for optimistic
|
// An opaque value that represents the version of this resource. May be used for optimistic
|
||||||
// concurrency, change detection, and the watch operation on a resource or set of resources.
|
// concurrency, change detection, and the watch operation on a resource or set of resources.
|
||||||
@ -1004,12 +1004,12 @@ type OperationList struct {
|
|||||||
|
|
||||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||||
type ObjectReference struct {
|
type ObjectReference struct {
|
||||||
Kind string `json:"kind,omitempty"`
|
Kind string `json:"kind,omitempty"`
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
UID string `json:"uid,omitempty"`
|
UID util.UID `json:"uid,omitempty"`
|
||||||
APIVersion string `json:"apiVersion,omitempty"`
|
APIVersion string `json:"apiVersion,omitempty"`
|
||||||
ResourceVersion string `json:"resourceVersion,omitempty"`
|
ResourceVersion string `json:"resourceVersion,omitempty"`
|
||||||
|
|
||||||
// Optional. If referring to a piece of an object instead of an entire object, this string
|
// Optional. If referring to a piece of an object instead of an entire object, this string
|
||||||
// should contain information to identify the sub-object. For example, if the object
|
// should contain information to identify the sub-object. For example, if the object
|
||||||
@ -1085,7 +1085,7 @@ type ContainerManifest struct {
|
|||||||
// TODO: UUID on Manifest is deprecated in the future once we are done
|
// TODO: UUID on Manifest is deprecated in the future once we are done
|
||||||
// with the API refactoring. It is required for now to determine the instance
|
// with the API refactoring. It is required for now to determine the instance
|
||||||
// of a Pod.
|
// of a Pod.
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID util.UID `json:"uuid,omitempty"`
|
||||||
Volumes []Volume `json:"volumes"`
|
Volumes []Volume `json:"volumes"`
|
||||||
Containers []Container `json:"containers"`
|
Containers []Container `json:"containers"`
|
||||||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
|
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
|
||||||
|
@ -56,7 +56,7 @@ type ContainerManifest struct {
|
|||||||
// TODO: UUID on Manifext is deprecated in the future once we are done
|
// TODO: UUID on Manifext is deprecated in the future once we are done
|
||||||
// with the API refactory. It is required for now to determine the instance
|
// with the API refactory. It is required for now to determine the instance
|
||||||
// of a Pod.
|
// of a Pod.
|
||||||
UUID string `json:"uuid,omitempty" description:"manifest UUID"`
|
UUID util.UID `json:"uuid,omitempty" description:"manifest UUID"`
|
||||||
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
|
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
|
||||||
Containers []Container `json:"containers" description:"list of containers belonging to the pod"`
|
Containers []Container `json:"containers" description:"list of containers belonging to the pod"`
|
||||||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
||||||
@ -297,7 +297,7 @@ type Lifecycle struct {
|
|||||||
type TypeMeta struct {
|
type TypeMeta struct {
|
||||||
Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase"`
|
Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase"`
|
||||||
ID string `json:"id,omitempty" description:"name of the object; must be a DNS_SUBDOMAIN and unique among all objects of the same kind within the same namespace; used in resource URLs"`
|
ID string `json:"id,omitempty" description:"name of the object; must be a DNS_SUBDOMAIN and unique among all objects of the same kind within the same namespace; used in resource URLs"`
|
||||||
UID string `json:"uid,omitempty" description:"UUID assigned by the system upon creation, unique across space and time"`
|
UID util.UID `json:"uid,omitempty" description:"UUID assigned by the system upon creation, unique across space and time"`
|
||||||
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; recorded by the system; null for lists"`
|
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; recorded by the system; null for lists"`
|
||||||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object"`
|
SelfLink string `json:"selfLink,omitempty" description:"URL for the object"`
|
||||||
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; value must be treated as opaque by clients and passed unmodified back to the server"`
|
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; value must be treated as opaque by clients and passed unmodified back to the server"`
|
||||||
@ -776,12 +776,12 @@ type ServerOpList struct {
|
|||||||
|
|
||||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||||
type ObjectReference struct {
|
type ObjectReference struct {
|
||||||
Kind string `json:"kind,omitempty" description:"kind of the referent"`
|
Kind string `json:"kind,omitempty" description:"kind of the referent"`
|
||||||
Namespace string `json:"namespace,omitempty" description:"namespace of the referent"`
|
Namespace string `json:"namespace,omitempty" description:"namespace of the referent"`
|
||||||
ID string `json:"name,omitempty" description:"id of the referent"`
|
ID string `json:"name,omitempty" description:"id of the referent"`
|
||||||
UID string `json:"uid,omitempty" description:"uid of the referent"`
|
UID util.UID `json:"uid,omitempty" description:"uid of the referent"`
|
||||||
APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"`
|
APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"`
|
||||||
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
|
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
|
||||||
|
|
||||||
// Optional. If referring to a piece of an object instead of an entire object, this string
|
// Optional. If referring to a piece of an object instead of an entire object, this string
|
||||||
// should contain information to identify the sub-object. For example, if the object
|
// should contain information to identify the sub-object. For example, if the object
|
||||||
|
@ -260,7 +260,7 @@ type Lifecycle struct {
|
|||||||
type TypeMeta struct {
|
type TypeMeta struct {
|
||||||
Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase"`
|
Kind string `json:"kind,omitempty" description:"kind of object, in CamelCase"`
|
||||||
ID string `json:"id,omitempty" description:"name of the object; must be a DNS_SUBDOMAIN and unique among all objects of the same kind within the same namespace; used in resource URLs"`
|
ID string `json:"id,omitempty" description:"name of the object; must be a DNS_SUBDOMAIN and unique among all objects of the same kind within the same namespace; used in resource URLs"`
|
||||||
UID string `json:"uid,omitempty" description:"UUID assigned by the system upon creation, unique across space and time"`
|
UID util.UID `json:"uid,omitempty" description:"UUID assigned by the system upon creation, unique across space and time"`
|
||||||
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; recorded by the system; null for lists"`
|
CreationTimestamp util.Time `json:"creationTimestamp,omitempty" description:"RFC 3339 date and time at which the object was created; recorded by the system; null for lists"`
|
||||||
SelfLink string `json:"selfLink,omitempty" description:"URL for the object"`
|
SelfLink string `json:"selfLink,omitempty" description:"URL for the object"`
|
||||||
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; value must be treated as opaque by clients and passed unmodified back to the server"`
|
ResourceVersion uint64 `json:"resourceVersion,omitempty" description:"string that identifies the internal version of this object that can be used by clients to determine when objects have changed; value must be treated as opaque by clients and passed unmodified back to the server"`
|
||||||
@ -749,12 +749,12 @@ type ServerOpList struct {
|
|||||||
|
|
||||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||||
type ObjectReference struct {
|
type ObjectReference struct {
|
||||||
Kind string `json:"kind,omitempty" description:"kind of the referent"`
|
Kind string `json:"kind,omitempty" description:"kind of the referent"`
|
||||||
Namespace string `json:"namespace,omitempty" description:"namespace of the referent"`
|
Namespace string `json:"namespace,omitempty" description:"namespace of the referent"`
|
||||||
ID string `json:"name,omitempty" description:"id of the referent"`
|
ID string `json:"name,omitempty" description:"id of the referent"`
|
||||||
UID string `json:"uid,omitempty" description:"uid of the referent"`
|
UID util.UID `json:"uid,omitempty" description:"uid of the referent"`
|
||||||
APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"`
|
APIVersion string `json:"apiVersion,omitempty" description:"API version of the referent"`
|
||||||
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
|
ResourceVersion string `json:"resourceVersion,omitempty" description:"specific resourceVersion to which this reference is made, if any"`
|
||||||
|
|
||||||
// Optional. If referring to a piece of an object instead of an entire object, this string
|
// Optional. If referring to a piece of an object instead of an entire object, this string
|
||||||
// should contain information to identify the sub-object. For example, if the object
|
// should contain information to identify the sub-object. For example, if the object
|
||||||
@ -824,7 +824,7 @@ type ContainerManifest struct {
|
|||||||
// TODO: UUID on Manifext is deprecated in the future once we are done
|
// TODO: UUID on Manifext is deprecated in the future once we are done
|
||||||
// with the API refactory. It is required for now to determine the instance
|
// with the API refactory. It is required for now to determine the instance
|
||||||
// of a Pod.
|
// of a Pod.
|
||||||
UUID string `json:"uuid,omitempty" description:"manifest UUID"`
|
UUID util.UID `json:"uuid,omitempty" description:"manifest UUID"`
|
||||||
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
|
Volumes []Volume `json:"volumes" description:"list of volumes that can be mounted by containers belonging to the pod"`
|
||||||
Containers []Container `json:"containers" description:"list of containers belonging to the pod"`
|
Containers []Container `json:"containers" description:"list of containers belonging to the pod"`
|
||||||
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty" description:"restart policy for all containers within the pod; one of RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyNever"`
|
||||||
|
@ -93,7 +93,7 @@ type ObjectMeta struct {
|
|||||||
// UID is the unique in time and space value for this object. It is typically generated by
|
// UID is the unique in time and space value for this object. It is typically generated by
|
||||||
// the server on successful creation of a resource and is not allowed to change on PUT
|
// the server on successful creation of a resource and is not allowed to change on PUT
|
||||||
// operations.
|
// operations.
|
||||||
UID string `json:"uid,omitempty"`
|
UID util.UID `json:"uid,omitempty"`
|
||||||
|
|
||||||
// An opaque value that represents the version of this resource. May be used for optimistic
|
// An opaque value that represents the version of this resource. May be used for optimistic
|
||||||
// concurrency, change detection, and the watch operation on a resource or set of resources.
|
// concurrency, change detection, and the watch operation on a resource or set of resources.
|
||||||
@ -138,7 +138,7 @@ const (
|
|||||||
// // TODO: UUID on Manifest is deprecated in the future once we are done
|
// // TODO: UUID on Manifest is deprecated in the future once we are done
|
||||||
// // with the API refactoring. It is required for now to determine the instance
|
// // with the API refactoring. It is required for now to determine the instance
|
||||||
// // of a Pod.
|
// // of a Pod.
|
||||||
// UUID string `json:"uuid,omitempty"`
|
// UUID util.UID `json:"uuid,omitempty"`
|
||||||
// Volumes []Volume `json:"volumes"`
|
// Volumes []Volume `json:"volumes"`
|
||||||
// Containers []Container `json:"containers"`
|
// Containers []Container `json:"containers"`
|
||||||
// RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
|
// RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
|
||||||
@ -995,12 +995,12 @@ type OperationList struct {
|
|||||||
|
|
||||||
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
// ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||||
type ObjectReference struct {
|
type ObjectReference struct {
|
||||||
Kind string `json:"kind,omitempty"`
|
Kind string `json:"kind,omitempty"`
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
UID string `json:"uid,omitempty"`
|
UID util.UID `json:"uid,omitempty"`
|
||||||
APIVersion string `json:"apiVersion,omitempty"`
|
APIVersion string `json:"apiVersion,omitempty"`
|
||||||
ResourceVersion string `json:"resourceVersion,omitempty"`
|
ResourceVersion string `json:"resourceVersion,omitempty"`
|
||||||
|
|
||||||
// Optional. If referring to a piece of an object instead of an entire object, this string
|
// Optional. If referring to a piece of an object instead of an entire object, this string
|
||||||
// should contain information to identify the sub-object. For example, if the object
|
// should contain information to identify the sub-object. For example, if the object
|
||||||
|
@ -136,7 +136,7 @@ func (e *events) Search(objOrRef runtime.Object) (*api.EventList, error) {
|
|||||||
fields["involvedObject.name"] = ref.Name
|
fields["involvedObject.name"] = ref.Name
|
||||||
}
|
}
|
||||||
if ref.UID != "" {
|
if ref.UID != "" {
|
||||||
fields["involvedObject.uid"] = ref.UID
|
fields["involvedObject.uid"] = string(ref.UID)
|
||||||
}
|
}
|
||||||
return e.List(labels.Everything(), fields.AsSelector())
|
return e.List(labels.Everything(), fields.AsSelector())
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,14 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultHealthyOutput = "ok"
|
const defaultHealthyOutput = "ok"
|
||||||
|
|
||||||
type CommandRunner interface {
|
type CommandRunner interface {
|
||||||
RunInContainer(podFullName, uuid, containerName string, cmd []string) ([]byte, error)
|
RunInContainer(podFullName string, uid util.UID, containerName string, cmd []string) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ExecHealthChecker struct {
|
type ExecHealthChecker struct {
|
||||||
@ -38,11 +39,11 @@ func NewExecHealthChecker(runner CommandRunner) HealthChecker {
|
|||||||
return &ExecHealthChecker{runner}
|
return &ExecHealthChecker{runner}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ExecHealthChecker) HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (Status, error) {
|
func (e *ExecHealthChecker) HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (Status, error) {
|
||||||
if container.LivenessProbe.Exec == nil {
|
if container.LivenessProbe.Exec == nil {
|
||||||
return Unknown, fmt.Errorf("missing exec parameters")
|
return Unknown, fmt.Errorf("missing exec parameters")
|
||||||
}
|
}
|
||||||
data, err := e.runner.RunInContainer(podFullName, podUUID, container.Name, container.LivenessProbe.Exec.Command)
|
data, err := e.runner.RunInContainer(podFullName, podUID, container.Name, container.LivenessProbe.Exec.Command)
|
||||||
glog.V(1).Infof("container %s health check response: %s", podFullName, string(data))
|
glog.V(1).Infof("container %s health check response: %s", podFullName, string(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Unknown, err
|
return Unknown, err
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FakeExec struct {
|
type FakeExec struct {
|
||||||
@ -30,7 +31,7 @@ type FakeExec struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeExec) RunInContainer(podFullName, uuid, container string, cmd []string) ([]byte, error) {
|
func (f *FakeExec) RunInContainer(podFullName string, uid util.UID, container string, cmd []string) ([]byte, error) {
|
||||||
f.cmd = cmd
|
f.cmd = cmd
|
||||||
return f.out, f.err
|
return f.out, f.err
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ const (
|
|||||||
|
|
||||||
// HealthChecker defines an abstract interface for checking container health.
|
// HealthChecker defines an abstract interface for checking container health.
|
||||||
type HealthChecker interface {
|
type HealthChecker interface {
|
||||||
HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (Status, error)
|
HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (Status, error)
|
||||||
CanCheck(probe *api.LivenessProbe) bool
|
CanCheck(probe *api.LivenessProbe) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,13 +79,13 @@ func (m *muxHealthChecker) findCheckerFor(probe *api.LivenessProbe) HealthChecke
|
|||||||
|
|
||||||
// HealthCheck delegates the health-checking of the container to one of the bundled implementations.
|
// HealthCheck delegates the health-checking of the container to one of the bundled implementations.
|
||||||
// If there is no health checker that can check container it returns Unknown, nil.
|
// If there is no health checker that can check container it returns Unknown, nil.
|
||||||
func (m *muxHealthChecker) HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (Status, error) {
|
func (m *muxHealthChecker) HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (Status, error) {
|
||||||
checker := m.findCheckerFor(container.LivenessProbe)
|
checker := m.findCheckerFor(container.LivenessProbe)
|
||||||
if checker == nil {
|
if checker == nil {
|
||||||
glog.Warningf("Failed to find health checker for %s %+v", container.Name, container.LivenessProbe)
|
glog.Warningf("Failed to find health checker for %s %+v", container.Name, container.LivenessProbe)
|
||||||
return Unknown, nil
|
return Unknown, nil
|
||||||
}
|
}
|
||||||
return checker.HealthCheck(podFullName, podUUID, status, container)
|
return checker.HealthCheck(podFullName, podUID, status, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *muxHealthChecker) CanCheck(probe *api.LivenessProbe) bool {
|
func (m *muxHealthChecker) CanCheck(probe *api.LivenessProbe) bool {
|
||||||
|
@ -105,7 +105,7 @@ func DoHTTPCheck(url string, client HTTPGetInterface) (Status, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HealthCheck checks if the container is healthy by trying sending HTTP Get requests to the container.
|
// HealthCheck checks if the container is healthy by trying sending HTTP Get requests to the container.
|
||||||
func (h *HTTPHealthChecker) HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (Status, error) {
|
func (h *HTTPHealthChecker) HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (Status, error) {
|
||||||
host, port, path, err := getURLParts(status, container)
|
host, port, path, err := getURLParts(status, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Unknown, err
|
return Unknown, err
|
||||||
|
@ -74,7 +74,7 @@ func DoTCPCheck(addr string) (Status, error) {
|
|||||||
return Healthy, nil
|
return Healthy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TCPHealthChecker) HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (Status, error) {
|
func (t *TCPHealthChecker) HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (Status, error) {
|
||||||
host, port, err := getTCPAddrParts(status, container)
|
host, port, err := getTCPAddrParts(status, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Unknown, err
|
return Unknown, err
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/dockertools"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
cadvisor "github.com/google/cadvisor/info"
|
cadvisor "github.com/google/cadvisor/info"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ func (kl *Kubelet) statsFromDockerContainer(cc cadvisorInterface, containerId st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetContainerInfo returns stats (from Cadvisor) for a container.
|
// GetContainerInfo returns stats (from Cadvisor) for a container.
|
||||||
func (kl *Kubelet) GetContainerInfo(podFullName, uuid, containerName string, req *cadvisor.ContainerInfoRequest) (*cadvisor.ContainerInfo, error) {
|
func (kl *Kubelet) GetContainerInfo(podFullName string, uid util.UID, containerName string, req *cadvisor.ContainerInfoRequest) (*cadvisor.ContainerInfo, error) {
|
||||||
cc := kl.GetCadvisorClient()
|
cc := kl.GetCadvisorClient()
|
||||||
if cc == nil {
|
if cc == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -62,7 +63,7 @@ func (kl *Kubelet) GetContainerInfo(podFullName, uuid, containerName string, req
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uuid, containerName)
|
dockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, containerName)
|
||||||
if !found {
|
if !found {
|
||||||
return nil, fmt.Errorf("couldn't find container")
|
return nil, fmt.Errorf("couldn't find container")
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -52,7 +53,7 @@ func (s sortedPods) Less(i, j int) bool {
|
|||||||
func CreateValidPod(name, namespace, source string) api.BoundPod {
|
func CreateValidPod(name, namespace, source string) api.BoundPod {
|
||||||
return api.BoundPod{
|
return api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
UID: name, // for the purpose of testing, this is unique enough
|
UID: util.UID(name), // for the purpose of testing, this is unique enough
|
||||||
Name: name,
|
Name: name,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Annotations: map[string]string{kubelet.ConfigSourceAnnotationKey: source},
|
Annotations: map[string]string{kubelet.ConfigSourceAnnotationKey: source},
|
||||||
|
@ -164,7 +164,7 @@ func extractFromFile(filename string) (api.BoundPod, error) {
|
|||||||
fmt.Fprintf(hasher, "host:%s", hostname)
|
fmt.Fprintf(hasher, "host:%s", hostname)
|
||||||
fmt.Fprintf(hasher, "file:%s", filename)
|
fmt.Fprintf(hasher, "file:%s", filename)
|
||||||
util.DeepHashObject(hasher, pod)
|
util.DeepHashObject(hasher, pod)
|
||||||
pod.UID = hex.EncodeToString(hasher.Sum(nil)[0:])
|
pod.UID = util.UID(hex.EncodeToString(hasher.Sum(nil)[0:]))
|
||||||
glog.V(5).Infof("Generated UID %q for pod %q from file %s", pod.UID, pod.Name, filename)
|
glog.V(5).Infof("Generated UID %q for pod %q from file %s", pod.UID, pod.Name, filename)
|
||||||
}
|
}
|
||||||
if len(pod.Namespace) == 0 {
|
if len(pod.Namespace) == 0 {
|
||||||
|
@ -28,12 +28,13 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExampleManifestAndPod(id string) (api.ContainerManifest, api.BoundPod) {
|
func ExampleManifestAndPod(id string) (api.ContainerManifest, api.BoundPod) {
|
||||||
manifest := api.ContainerManifest{
|
manifest := api.ContainerManifest{
|
||||||
ID: id,
|
ID: id,
|
||||||
UUID: id,
|
UUID: util.UID(id),
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
{
|
{
|
||||||
Name: "c" + id,
|
Name: "c" + id,
|
||||||
@ -53,7 +54,7 @@ func ExampleManifestAndPod(id string) (api.ContainerManifest, api.BoundPod) {
|
|||||||
expectedPod := api.BoundPod{
|
expectedPod := api.BoundPod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
Name: id,
|
Name: id,
|
||||||
UID: id,
|
UID: util.UID(id),
|
||||||
},
|
},
|
||||||
Spec: api.PodSpec{
|
Spec: api.PodSpec{
|
||||||
Containers: []api.Container{
|
Containers: []api.Container{
|
||||||
|
@ -147,7 +147,7 @@ func applyDefaults(pod *api.BoundPod, url string) {
|
|||||||
hasher := md5.New()
|
hasher := md5.New()
|
||||||
fmt.Fprintf(hasher, "url:%s", url)
|
fmt.Fprintf(hasher, "url:%s", url)
|
||||||
util.DeepHashObject(hasher, pod)
|
util.DeepHashObject(hasher, pod)
|
||||||
pod.UID = hex.EncodeToString(hasher.Sum(nil)[0:])
|
pod.UID = util.UID(hex.EncodeToString(hasher.Sum(nil)[0:]))
|
||||||
glog.V(5).Infof("Generated UID %q for pod %q from URL %s", pod.UID, pod.Name, url)
|
glog.V(5).Infof("Generated UID %q for pod %q from URL %s", pod.UID, pod.Name, url)
|
||||||
}
|
}
|
||||||
if len(pod.Namespace) == 0 {
|
if len(pod.Namespace) == 0 {
|
||||||
|
@ -254,7 +254,7 @@ func (p throttledDockerPuller) IsImagePresent(name string) (bool, error) {
|
|||||||
// DockerContainers is a map of containers
|
// DockerContainers is a map of containers
|
||||||
type DockerContainers map[DockerID]*docker.APIContainers
|
type DockerContainers map[DockerID]*docker.APIContainers
|
||||||
|
|
||||||
func (c DockerContainers) FindPodContainer(podFullName, uuid, containerName string) (*docker.APIContainers, bool, uint64) {
|
func (c DockerContainers) FindPodContainer(podFullName string, uid util.UID, containerName string) (*docker.APIContainers, bool, uint64) {
|
||||||
for _, dockerContainer := range c {
|
for _, dockerContainer := range c {
|
||||||
if len(dockerContainer.Names) == 0 {
|
if len(dockerContainer.Names) == 0 {
|
||||||
continue
|
continue
|
||||||
@ -262,7 +262,7 @@ func (c DockerContainers) FindPodContainer(podFullName, uuid, containerName stri
|
|||||||
// TODO(proppy): build the docker container name and do a map lookup instead?
|
// TODO(proppy): build the docker container name and do a map lookup instead?
|
||||||
dockerManifestID, dockerUUID, dockerContainerName, hash := ParseDockerName(dockerContainer.Names[0])
|
dockerManifestID, dockerUUID, dockerContainerName, hash := ParseDockerName(dockerContainer.Names[0])
|
||||||
if dockerManifestID == podFullName &&
|
if dockerManifestID == podFullName &&
|
||||||
(uuid == "" || dockerUUID == uuid) &&
|
(uid == "" || dockerUUID == uid) &&
|
||||||
dockerContainerName == containerName {
|
dockerContainerName == containerName {
|
||||||
return dockerContainer, true, hash
|
return dockerContainer, true, hash
|
||||||
}
|
}
|
||||||
@ -313,8 +313,8 @@ func GetKubeletDockerContainers(client DockerInterface, allContainers bool) (Doc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRecentDockerContainersWithNameAndUUID returns a list of dead docker containers which matches the name
|
// GetRecentDockerContainersWithNameAndUUID returns a list of dead docker containers which matches the name
|
||||||
// and uuid given.
|
// and uid given.
|
||||||
func GetRecentDockerContainersWithNameAndUUID(client DockerInterface, podFullName, uuid, containerName string) ([]*docker.Container, error) {
|
func GetRecentDockerContainersWithNameAndUUID(client DockerInterface, podFullName string, uid util.UID, containerName string) ([]*docker.Container, error) {
|
||||||
var result []*docker.Container
|
var result []*docker.Container
|
||||||
containers, err := client.ListContainers(docker.ListContainersOptions{All: true})
|
containers, err := client.ListContainers(docker.ListContainersOptions{All: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -328,7 +328,7 @@ func GetRecentDockerContainersWithNameAndUUID(client DockerInterface, podFullNam
|
|||||||
if dockerPodName != podFullName {
|
if dockerPodName != podFullName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uuid != "" && dockerUUID != uuid {
|
if uid != "" && dockerUUID != uid {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if dockerContainerName != containerName {
|
if dockerContainerName != containerName {
|
||||||
@ -447,7 +447,7 @@ func inspectContainer(client DockerInterface, dockerID, containerName, tPath str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDockerPodInfo returns docker info for all containers in the pod/manifest.
|
// GetDockerPodInfo returns docker info for all containers in the pod/manifest.
|
||||||
func GetDockerPodInfo(client DockerInterface, manifest api.PodSpec, podFullName, uuid string) (api.PodInfo, error) {
|
func GetDockerPodInfo(client DockerInterface, manifest api.PodSpec, podFullName string, uid util.UID) (api.PodInfo, error) {
|
||||||
info := api.PodInfo{}
|
info := api.PodInfo{}
|
||||||
expectedContainers := make(map[string]api.Container)
|
expectedContainers := make(map[string]api.Container)
|
||||||
for _, container := range manifest.Containers {
|
for _, container := range manifest.Containers {
|
||||||
@ -468,7 +468,7 @@ func GetDockerPodInfo(client DockerInterface, manifest api.PodSpec, podFullName,
|
|||||||
if dockerManifestID != podFullName {
|
if dockerManifestID != podFullName {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if uuid != "" && dockerUUID != uuid {
|
if uid != "" && dockerUUID != uid {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c, found := expectedContainers[dockerContainerName]
|
c, found := expectedContainers[dockerContainerName]
|
||||||
@ -545,7 +545,7 @@ func HashContainer(container *api.Container) uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Creates a name which can be reversed to identify both full pod name and container name.
|
// Creates a name which can be reversed to identify both full pod name and container name.
|
||||||
func BuildDockerName(podUID, podFullName string, container *api.Container) string {
|
func BuildDockerName(podUID util.UID, podFullName string, container *api.Container) string {
|
||||||
containerName := container.Name + "." + strconv.FormatUint(HashContainer(container), 16)
|
containerName := container.Name + "." + strconv.FormatUint(HashContainer(container), 16)
|
||||||
return fmt.Sprintf("%s_%s_%s_%s_%08x",
|
return fmt.Sprintf("%s_%s_%s_%s_%08x",
|
||||||
containerNamePrefix,
|
containerNamePrefix,
|
||||||
@ -557,7 +557,7 @@ func BuildDockerName(podUID, podFullName string, container *api.Container) strin
|
|||||||
|
|
||||||
// Unpacks a container name, returning the pod full name and container name we would have used to
|
// Unpacks a container name, returning the pod full name and container name we would have used to
|
||||||
// construct the docker name. If the docker name isn't the one we created, we may return empty strings.
|
// construct the docker name. If the docker name isn't the one we created, we may return empty strings.
|
||||||
func ParseDockerName(name string) (podFullName, podUID, containerName string, hash uint64) {
|
func ParseDockerName(name string) (podFullName string, podUID util.UID, containerName string, hash uint64) {
|
||||||
// For some reason docker appears to be appending '/' to names.
|
// For some reason docker appears to be appending '/' to names.
|
||||||
// If it's there, strip it.
|
// If it's there, strip it.
|
||||||
if name[0] == '/' {
|
if name[0] == '/' {
|
||||||
@ -590,7 +590,7 @@ func ParseDockerName(name string) (podFullName, podUID, containerName string, ha
|
|||||||
podFullName = parts[2]
|
podFullName = parts[2]
|
||||||
|
|
||||||
// Pod UID.
|
// Pod UID.
|
||||||
podUID = parts[3]
|
podUID = util.UID(parts[3])
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,9 @@ func verifyPackUnpack(t *testing.T, podNamespace, podUID, podName, containerName
|
|||||||
util.DeepHashObject(hasher, *container)
|
util.DeepHashObject(hasher, *container)
|
||||||
computedHash := uint64(hasher.Sum32())
|
computedHash := uint64(hasher.Sum32())
|
||||||
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
||||||
name := BuildDockerName(podUID, podFullName, container)
|
name := BuildDockerName(util.UID(podUID), podFullName, container)
|
||||||
returnedPodFullName, returnedUID, returnedContainerName, hash := ParseDockerName(name)
|
returnedPodFullName, returnedUID, returnedContainerName, hash := ParseDockerName(name)
|
||||||
if podFullName != returnedPodFullName || podUID != returnedUID || containerName != returnedContainerName || computedHash != hash {
|
if podFullName != returnedPodFullName || podUID != string(returnedUID) || containerName != returnedContainerName || computedHash != hash {
|
||||||
t.Errorf("For (%s, %s, %s, %d), unpacked (%s, %s, %s, %d)", podFullName, podUID, containerName, computedHash, returnedPodFullName, returnedUID, returnedContainerName, hash)
|
t.Errorf("For (%s, %s, %s, %d), unpacked (%s, %s, %s, %d)", podFullName, podUID, containerName, computedHash, returnedPodFullName, returnedUID, returnedContainerName, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ func TestContainerManifestNaming(t *testing.T) {
|
|||||||
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s.%s", podName, podNamespace)
|
||||||
|
|
||||||
returnedPodFullName, returnedPodUID, returnedContainerName, hash := ParseDockerName(name)
|
returnedPodFullName, returnedPodUID, returnedContainerName, hash := ParseDockerName(name)
|
||||||
if returnedPodFullName != podFullName || returnedPodUID != podUID || returnedContainerName != container.Name || hash != 0 {
|
if returnedPodFullName != podFullName || string(returnedPodUID) != podUID || returnedContainerName != container.Name || hash != 0 {
|
||||||
t.Errorf("unexpected parse: %s %s %s %d", returnedPodFullName, returnedPodUID, returnedContainerName, hash)
|
t.Errorf("unexpected parse: %s %s %s %d", returnedPodFullName, returnedPodUID, returnedContainerName, hash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ type execActionHandler struct {
|
|||||||
kubelet *Kubelet
|
kubelet *Kubelet
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *execActionHandler) Run(podFullName, uuid string, container *api.Container, handler *api.Handler) error {
|
func (e *execActionHandler) Run(podFullName string, uid util.UID, container *api.Container, handler *api.Handler) error {
|
||||||
_, err := e.kubelet.RunInContainer(podFullName, uuid, container.Name, handler.Exec.Command)
|
_, err := e.kubelet.RunInContainer(podFullName, uid, container.Name, handler.Exec.Command)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +67,11 @@ func ResolvePort(portReference util.IntOrString, container *api.Container) (int,
|
|||||||
return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container)
|
return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpActionHandler) Run(podFullName, uuid string, container *api.Container, handler *api.Handler) error {
|
func (h *httpActionHandler) Run(podFullName string, uid util.UID, container *api.Container, handler *api.Handler) error {
|
||||||
host := handler.HTTPGet.Host
|
host := handler.HTTPGet.Host
|
||||||
if len(host) == 0 {
|
if len(host) == 0 {
|
||||||
var info api.PodInfo
|
var info api.PodInfo
|
||||||
info, err := h.kubelet.GetPodInfo(podFullName, uuid)
|
info, err := h.kubelet.GetPodInfo(podFullName, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("unable to get pod info, event handlers may be invalid.")
|
glog.Errorf("unable to get pod info, event handlers may be invalid.")
|
||||||
return err
|
return err
|
||||||
|
@ -186,16 +186,16 @@ func (kl *Kubelet) GetPodsDir() string {
|
|||||||
|
|
||||||
// GetPodDir returns the full path to the per-pod data directory for the
|
// GetPodDir returns the full path to the per-pod data directory for the
|
||||||
// specified pod. This directory may not exist if the pod does not exist.
|
// specified pod. This directory may not exist if the pod does not exist.
|
||||||
func (kl *Kubelet) GetPodDir(podUID string) string {
|
func (kl *Kubelet) GetPodDir(podUID util.UID) string {
|
||||||
// Backwards compat. The "old" stuff should be removed before 1.0
|
// Backwards compat. The "old" stuff should be removed before 1.0
|
||||||
// release. The thinking here is this:
|
// release. The thinking here is this:
|
||||||
// !old && !new = use new
|
// !old && !new = use new
|
||||||
// !old && new = use new
|
// !old && new = use new
|
||||||
// old && !new = use old
|
// old && !new = use old
|
||||||
// old && new = use new (but warn)
|
// old && new = use new (but warn)
|
||||||
oldPath := path.Join(kl.GetRootDir(), podUID)
|
oldPath := path.Join(kl.GetRootDir(), string(podUID))
|
||||||
oldExists := dirExists(oldPath)
|
oldExists := dirExists(oldPath)
|
||||||
newPath := path.Join(kl.GetPodsDir(), podUID)
|
newPath := path.Join(kl.GetPodsDir(), string(podUID))
|
||||||
newExists := dirExists(newPath)
|
newExists := dirExists(newPath)
|
||||||
if oldExists && !newExists {
|
if oldExists && !newExists {
|
||||||
return oldPath
|
return oldPath
|
||||||
@ -209,14 +209,14 @@ func (kl *Kubelet) GetPodDir(podUID string) string {
|
|||||||
// GetPodVolumesDir returns the full path to the per-pod data directory under
|
// GetPodVolumesDir returns the full path to the per-pod data directory under
|
||||||
// which volumes are created for the specified pod. This directory may not
|
// which volumes are created for the specified pod. This directory may not
|
||||||
// exist if the pod does not exist.
|
// exist if the pod does not exist.
|
||||||
func (kl *Kubelet) GetPodVolumesDir(podUID string) string {
|
func (kl *Kubelet) GetPodVolumesDir(podUID util.UID) string {
|
||||||
return path.Join(kl.GetPodDir(podUID), "volumes")
|
return path.Join(kl.GetPodDir(podUID), "volumes")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPodContainerDir returns the full path to the per-pod data directory under
|
// GetPodContainerDir returns the full path to the per-pod data directory under
|
||||||
// which container data is held for the specified pod. This directory may not
|
// which container data is held for the specified pod. This directory may not
|
||||||
// exist if the pod or container does not exist.
|
// exist if the pod or container does not exist.
|
||||||
func (kl *Kubelet) GetPodContainerDir(podUID, ctrName string) string {
|
func (kl *Kubelet) GetPodContainerDir(podUID util.UID, ctrName string) string {
|
||||||
// Backwards compat. The "old" stuff should be removed before 1.0
|
// Backwards compat. The "old" stuff should be removed before 1.0
|
||||||
// release. The thinking here is this:
|
// release. The thinking here is this:
|
||||||
// !old && !new = use new
|
// !old && !new = use new
|
||||||
@ -256,15 +256,15 @@ func (kl *Kubelet) setupDataDirs() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a list of pods that have data directories.
|
// Get a list of pods that have data directories.
|
||||||
func (kl *Kubelet) listPodsFromDisk() ([]string, error) {
|
func (kl *Kubelet) listPodsFromDisk() ([]util.UID, error) {
|
||||||
podInfos, err := ioutil.ReadDir(kl.GetPodsDir())
|
podInfos, err := ioutil.ReadDir(kl.GetPodsDir())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pods := []string{}
|
pods := []util.UID{}
|
||||||
for i := range podInfos {
|
for i := range podInfos {
|
||||||
if podInfos[i].IsDir() {
|
if podInfos[i].IsDir() {
|
||||||
pods = append(pods, podInfos[i].Name())
|
pods = append(pods, util.UID(podInfos[i].Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pods, nil
|
return pods, nil
|
||||||
@ -341,13 +341,13 @@ func (kl *Kubelet) GarbageCollectContainers() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
uuidToIDMap := map[string][]string{}
|
uidToIDMap := map[string][]string{}
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
_, uuid, name, _ := dockertools.ParseDockerName(container.ID)
|
_, uid, name, _ := dockertools.ParseDockerName(container.ID)
|
||||||
uuidName := uuid + "." + name
|
uidName := string(uid) + "." + name
|
||||||
uuidToIDMap[uuidName] = append(uuidToIDMap[uuidName], container.ID)
|
uidToIDMap[uidName] = append(uidToIDMap[uidName], container.ID)
|
||||||
}
|
}
|
||||||
for _, list := range uuidToIDMap {
|
for _, list := range uidToIDMap {
|
||||||
if len(list) <= kl.maxContainerCount {
|
if len(list) <= kl.maxContainerCount {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -516,7 +516,7 @@ func (kl *Kubelet) mountExternalVolumes(pod *api.BoundPod) (volumeMap, error) {
|
|||||||
|
|
||||||
// A basic interface that knows how to execute handlers
|
// A basic interface that knows how to execute handlers
|
||||||
type actionHandler interface {
|
type actionHandler interface {
|
||||||
Run(podFullName, uuid string, container *api.Container, handler *api.Handler) error
|
Run(podFullName string, uid util.UID, container *api.Container, handler *api.Handler) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *Kubelet) newActionHandler(handler *api.Handler) actionHandler {
|
func (kl *Kubelet) newActionHandler(handler *api.Handler) actionHandler {
|
||||||
@ -531,12 +531,12 @@ func (kl *Kubelet) newActionHandler(handler *api.Handler) actionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *Kubelet) runHandler(podFullName, uuid string, container *api.Container, handler *api.Handler) error {
|
func (kl *Kubelet) runHandler(podFullName string, uid util.UID, container *api.Container, handler *api.Handler) error {
|
||||||
actionHandler := kl.newActionHandler(handler)
|
actionHandler := kl.newActionHandler(handler)
|
||||||
if actionHandler == nil {
|
if actionHandler == nil {
|
||||||
return fmt.Errorf("invalid handler")
|
return fmt.Errorf("invalid handler")
|
||||||
}
|
}
|
||||||
return actionHandler.Run(podFullName, uuid, container, handler)
|
return actionHandler.Run(podFullName, uid, container, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fieldPath returns a fieldPath locating container within pod.
|
// fieldPath returns a fieldPath locating container within pod.
|
||||||
@ -865,22 +865,22 @@ type empty struct{}
|
|||||||
|
|
||||||
func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.DockerContainers) error {
|
func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.DockerContainers) error {
|
||||||
podFullName := GetPodFullName(pod)
|
podFullName := GetPodFullName(pod)
|
||||||
uuid := pod.UID
|
uid := pod.UID
|
||||||
containersToKeep := make(map[dockertools.DockerID]empty)
|
containersToKeep := make(map[dockertools.DockerID]empty)
|
||||||
killedContainers := make(map[dockertools.DockerID]empty)
|
killedContainers := make(map[dockertools.DockerID]empty)
|
||||||
glog.V(4).Infof("Syncing Pod, podFullName: %q, uuid: %q", podFullName, uuid)
|
glog.V(4).Infof("Syncing Pod, podFullName: %q, uid: %q", podFullName, uid)
|
||||||
|
|
||||||
// Make data dirs.
|
// Make data dirs.
|
||||||
if err := os.Mkdir(kl.GetPodDir(uuid), 0750); err != nil && !os.IsExist(err) {
|
if err := os.Mkdir(kl.GetPodDir(uid), 0750); err != nil && !os.IsExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.Mkdir(kl.GetPodVolumesDir(uuid), 0750); err != nil && !os.IsExist(err) {
|
if err := os.Mkdir(kl.GetPodVolumesDir(uid), 0750); err != nil && !os.IsExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we have a network container
|
// Make sure we have a network container
|
||||||
var netID dockertools.DockerID
|
var netID dockertools.DockerID
|
||||||
if netDockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uuid, networkContainerName); found {
|
if netDockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, networkContainerName); found {
|
||||||
netID = dockertools.DockerID(netDockerContainer.ID)
|
netID = dockertools.DockerID(netDockerContainer.ID)
|
||||||
} else {
|
} else {
|
||||||
glog.V(2).Infof("Network container doesn't exist for pod %q, killing and re-creating the pod", podFullName)
|
glog.V(2).Infof("Network container doesn't exist for pod %q, killing and re-creating the pod", podFullName)
|
||||||
@ -911,9 +911,9 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
}
|
}
|
||||||
|
|
||||||
podStatus := api.PodStatus{}
|
podStatus := api.PodStatus{}
|
||||||
info, err := kl.GetPodInfo(podFullName, uuid)
|
info, err := kl.GetPodInfo(podFullName, uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Unable to get pod with name %q and uuid %q info, health checks may be invalid", podFullName, uuid)
|
glog.Errorf("Unable to get pod with name %q and uid %q info, health checks may be invalid", podFullName, uid)
|
||||||
}
|
}
|
||||||
netInfo, found := info[networkContainerName]
|
netInfo, found := info[networkContainerName]
|
||||||
if found {
|
if found {
|
||||||
@ -922,14 +922,14 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
|
|
||||||
for _, container := range pod.Spec.Containers {
|
for _, container := range pod.Spec.Containers {
|
||||||
expectedHash := dockertools.HashContainer(&container)
|
expectedHash := dockertools.HashContainer(&container)
|
||||||
if dockerContainer, found, hash := dockerContainers.FindPodContainer(podFullName, uuid, container.Name); found {
|
if dockerContainer, found, hash := dockerContainers.FindPodContainer(podFullName, uid, container.Name); found {
|
||||||
containerID := dockertools.DockerID(dockerContainer.ID)
|
containerID := dockertools.DockerID(dockerContainer.ID)
|
||||||
glog.V(3).Infof("pod %q container %q exists as %v", podFullName, container.Name, containerID)
|
glog.V(3).Infof("pod %q container %q exists as %v", podFullName, container.Name, containerID)
|
||||||
|
|
||||||
// look for changes in the container.
|
// look for changes in the container.
|
||||||
if hash == 0 || hash == expectedHash {
|
if hash == 0 || hash == expectedHash {
|
||||||
// TODO: This should probably be separated out into a separate goroutine.
|
// TODO: This should probably be separated out into a separate goroutine.
|
||||||
healthy, err := kl.healthy(podFullName, uuid, podStatus, container, dockerContainer)
|
healthy, err := kl.healthy(podFullName, uid, podStatus, container, dockerContainer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(1).Infof("health check errored: %v", err)
|
glog.V(1).Infof("health check errored: %v", err)
|
||||||
containersToKeep[containerID] = empty{}
|
containersToKeep[containerID] = empty{}
|
||||||
@ -950,7 +950,7 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
killedContainers[containerID] = empty{}
|
killedContainers[containerID] = empty{}
|
||||||
|
|
||||||
// Also kill associated network container
|
// Also kill associated network container
|
||||||
if netContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uuid, networkContainerName); found {
|
if netContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, networkContainerName); found {
|
||||||
if err := kl.killContainer(netContainer); err != nil {
|
if err := kl.killContainer(netContainer); err != nil {
|
||||||
glog.V(1).Infof("Failed to kill network container %q: %v", netContainer.ID, err)
|
glog.V(1).Infof("Failed to kill network container %q: %v", netContainer.ID, err)
|
||||||
continue
|
continue
|
||||||
@ -959,29 +959,29 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check RestartPolicy for container
|
// Check RestartPolicy for container
|
||||||
recentContainers, err := dockertools.GetRecentDockerContainersWithNameAndUUID(kl.dockerClient, podFullName, uuid, container.Name)
|
recentContainers, err := dockertools.GetRecentDockerContainersWithNameAndUUID(kl.dockerClient, podFullName, uid, container.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Error listing recent containers with name and uuid:%s--%s--%s", podFullName, uuid, container.Name)
|
glog.Errorf("Error listing recent containers with name and uid:%s--%s--%s", podFullName, uid, container.Name)
|
||||||
// TODO(dawnchen): error handling here?
|
// TODO(dawnchen): error handling here?
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(recentContainers) > 0 && pod.Spec.RestartPolicy.Always == nil {
|
if len(recentContainers) > 0 && pod.Spec.RestartPolicy.Always == nil {
|
||||||
if pod.Spec.RestartPolicy.Never != nil {
|
if pod.Spec.RestartPolicy.Never != nil {
|
||||||
glog.V(3).Infof("Already ran container with name %s--%s--%s, do nothing",
|
glog.V(3).Infof("Already ran container with name %s--%s--%s, do nothing",
|
||||||
podFullName, uuid, container.Name)
|
podFullName, uid, container.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if pod.Spec.RestartPolicy.OnFailure != nil {
|
if pod.Spec.RestartPolicy.OnFailure != nil {
|
||||||
// Check the exit code of last run
|
// Check the exit code of last run
|
||||||
if recentContainers[0].State.ExitCode == 0 {
|
if recentContainers[0].State.ExitCode == 0 {
|
||||||
glog.V(3).Infof("Already successfully ran container with name %s--%s--%s, do nothing",
|
glog.V(3).Infof("Already successfully ran container with name %s--%s--%s, do nothing",
|
||||||
podFullName, uuid, container.Name)
|
podFullName, uid, container.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glog.V(3).Infof("Container with name %s--%s--%s doesn't exist, creating %#v", podFullName, uuid, container.Name, container)
|
glog.V(3).Infof("Container with name %s--%s--%s doesn't exist, creating %#v", podFullName, uid, container.Name, container)
|
||||||
ref, err := containerRef(pod, &container)
|
ref, err := containerRef(pod, &container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Couldn't make a ref to pod %v, container %v: '%v'", pod.Name, container.Name, err)
|
glog.Errorf("Couldn't make a ref to pod %v, container %v: '%v'", pod.Name, container.Name, err)
|
||||||
@ -1016,7 +1016,7 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
// Kill any containers in this pod which were not identified above (guards against duplicates).
|
// Kill any containers in this pod which were not identified above (guards against duplicates).
|
||||||
for id, container := range dockerContainers {
|
for id, container := range dockerContainers {
|
||||||
curPodFullName, curUUID, _, _ := dockertools.ParseDockerName(container.Names[0])
|
curPodFullName, curUUID, _, _ := dockertools.ParseDockerName(container.Names[0])
|
||||||
if curPodFullName == podFullName && curUUID == uuid {
|
if curPodFullName == podFullName && curUUID == uid {
|
||||||
// Don't kill containers we want to keep or those we already killed.
|
// Don't kill containers we want to keep or those we already killed.
|
||||||
_, keep := containersToKeep[id]
|
_, keep := containersToKeep[id]
|
||||||
_, killed := killedContainers[id]
|
_, killed := killedContainers[id]
|
||||||
@ -1035,7 +1035,7 @@ func (kl *Kubelet) syncPod(pod *api.BoundPod, dockerContainers dockertools.Docke
|
|||||||
|
|
||||||
type podContainer struct {
|
type podContainer struct {
|
||||||
podFullName string
|
podFullName string
|
||||||
uuid string
|
uid util.UID
|
||||||
containerName string
|
containerName string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1055,7 +1055,7 @@ func getDesiredVolumes(pods []api.BoundPod) map[string]api.Volume {
|
|||||||
func (kl *Kubelet) cleanupOrphanedPods(pods []api.BoundPod) error {
|
func (kl *Kubelet) cleanupOrphanedPods(pods []api.BoundPod) error {
|
||||||
desired := util.NewStringSet()
|
desired := util.NewStringSet()
|
||||||
for i := range pods {
|
for i := range pods {
|
||||||
desired.Insert(pods[i].UID)
|
desired.Insert(string(pods[i].UID))
|
||||||
}
|
}
|
||||||
found, err := kl.listPodsFromDisk()
|
found, err := kl.listPodsFromDisk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1063,7 +1063,7 @@ func (kl *Kubelet) cleanupOrphanedPods(pods []api.BoundPod) error {
|
|||||||
}
|
}
|
||||||
errlist := []error{}
|
errlist := []error{}
|
||||||
for i := range found {
|
for i := range found {
|
||||||
if !desired.Has(found[i]) {
|
if !desired.Has(string(found[i])) {
|
||||||
glog.V(3).Infof("Orphaned pod %q found, removing", found[i])
|
glog.V(3).Infof("Orphaned pod %q found, removing", found[i])
|
||||||
if err := os.RemoveAll(kl.GetPodDir(found[i])); err != nil {
|
if err := os.RemoveAll(kl.GetPodDir(found[i])); err != nil {
|
||||||
errlist = append(errlist, err)
|
errlist = append(errlist, err)
|
||||||
@ -1098,7 +1098,7 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error {
|
|||||||
glog.V(4).Infof("Desired: %#v", pods)
|
glog.V(4).Infof("Desired: %#v", pods)
|
||||||
var err error
|
var err error
|
||||||
desiredContainers := make(map[podContainer]empty)
|
desiredContainers := make(map[podContainer]empty)
|
||||||
desiredPods := make(map[string]empty)
|
desiredPods := make(map[util.UID]empty)
|
||||||
|
|
||||||
dockerContainers, err := dockertools.GetKubeletDockerContainers(kl.dockerClient, false)
|
dockerContainers, err := dockertools.GetKubeletDockerContainers(kl.dockerClient, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1110,13 +1110,13 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error {
|
|||||||
for ix := range pods {
|
for ix := range pods {
|
||||||
pod := &pods[ix]
|
pod := &pods[ix]
|
||||||
podFullName := GetPodFullName(pod)
|
podFullName := GetPodFullName(pod)
|
||||||
uuid := pod.UID
|
uid := pod.UID
|
||||||
desiredPods[uuid] = empty{}
|
desiredPods[uid] = empty{}
|
||||||
|
|
||||||
// Add all containers (including net) to the map.
|
// Add all containers (including net) to the map.
|
||||||
desiredContainers[podContainer{podFullName, uuid, networkContainerName}] = empty{}
|
desiredContainers[podContainer{podFullName, uid, networkContainerName}] = empty{}
|
||||||
for _, cont := range pod.Spec.Containers {
|
for _, cont := range pod.Spec.Containers {
|
||||||
desiredContainers[podContainer{podFullName, uuid, cont.Name}] = empty{}
|
desiredContainers[podContainer{podFullName, uid, cont.Name}] = empty{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the sync in an async manifest worker.
|
// Run the sync in an async manifest worker.
|
||||||
@ -1130,8 +1130,8 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error {
|
|||||||
// Kill any containers we don't need.
|
// Kill any containers we don't need.
|
||||||
for _, container := range dockerContainers {
|
for _, container := range dockerContainers {
|
||||||
// Don't kill containers that are in the desired pods.
|
// Don't kill containers that are in the desired pods.
|
||||||
podFullName, uuid, containerName, _ := dockertools.ParseDockerName(container.Names[0])
|
podFullName, uid, containerName, _ := dockertools.ParseDockerName(container.Names[0])
|
||||||
if _, found := desiredPods[uuid]; found {
|
if _, found := desiredPods[uid]; found {
|
||||||
// syncPod() will handle this one.
|
// syncPod() will handle this one.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1142,7 +1142,7 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error {
|
|||||||
glog.V(4).Infof("Skipping delete of container (%q), source (%s) aren't ready yet.", podFullName, source)
|
glog.V(4).Infof("Skipping delete of container (%q), source (%s) aren't ready yet.", podFullName, source)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pc := podContainer{podFullName, uuid, containerName}
|
pc := podContainer{podFullName, uid, containerName}
|
||||||
if _, ok := desiredContainers[pc]; !ok {
|
if _, ok := desiredContainers[pc]; !ok {
|
||||||
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
glog.V(1).Infof("Killing unwanted container %+v", pc)
|
||||||
err = kl.killContainer(container)
|
err = kl.killContainer(container)
|
||||||
@ -1169,7 +1169,7 @@ func (kl *Kubelet) SyncPods(pods []api.BoundPod) error {
|
|||||||
|
|
||||||
func updateBoundPods(changed []api.BoundPod, current []api.BoundPod) []api.BoundPod {
|
func updateBoundPods(changed []api.BoundPod, current []api.BoundPod) []api.BoundPod {
|
||||||
updated := []api.BoundPod{}
|
updated := []api.BoundPod{}
|
||||||
m := map[string]*api.BoundPod{}
|
m := map[util.UID]*api.BoundPod{}
|
||||||
for i := range changed {
|
for i := range changed {
|
||||||
pod := &changed[i]
|
pod := &changed[i]
|
||||||
m[pod.UID] = pod
|
m[pod.UID] = pod
|
||||||
@ -1277,7 +1277,7 @@ func (kl *Kubelet) GetPodByName(namespace, name string) (*api.BoundPod, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetPodInfo returns information from Docker about the containers in a pod
|
// GetPodInfo returns information from Docker about the containers in a pod
|
||||||
func (kl *Kubelet) GetPodInfo(podFullName, uuid string) (api.PodInfo, error) {
|
func (kl *Kubelet) GetPodInfo(podFullName string, uid util.UID) (api.PodInfo, error) {
|
||||||
var manifest api.PodSpec
|
var manifest api.PodSpec
|
||||||
for _, pod := range kl.pods {
|
for _, pod := range kl.pods {
|
||||||
if GetPodFullName(&pod) == podFullName {
|
if GetPodFullName(&pod) == podFullName {
|
||||||
@ -1285,10 +1285,10 @@ func (kl *Kubelet) GetPodInfo(podFullName, uuid string) (api.PodInfo, error) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dockertools.GetDockerPodInfo(kl.dockerClient, manifest, podFullName, uuid)
|
return dockertools.GetDockerPodInfo(kl.dockerClient, manifest, podFullName, uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kl *Kubelet) healthy(podFullName, podUUID string, status api.PodStatus, container api.Container, dockerContainer *docker.APIContainers) (health.Status, error) {
|
func (kl *Kubelet) healthy(podFullName string, podUID util.UID, status api.PodStatus, container api.Container, dockerContainer *docker.APIContainers) (health.Status, error) {
|
||||||
// Give the container 60 seconds to start up.
|
// Give the container 60 seconds to start up.
|
||||||
if container.LivenessProbe == nil {
|
if container.LivenessProbe == nil {
|
||||||
return health.Healthy, nil
|
return health.Healthy, nil
|
||||||
@ -1299,7 +1299,7 @@ func (kl *Kubelet) healthy(podFullName, podUUID string, status api.PodStatus, co
|
|||||||
if kl.healthChecker == nil {
|
if kl.healthChecker == nil {
|
||||||
return health.Healthy, nil
|
return health.Healthy, nil
|
||||||
}
|
}
|
||||||
return kl.healthChecker.HealthCheck(podFullName, podUUID, status, container)
|
return kl.healthChecker.HealthCheck(podFullName, podUID, status, container)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns logs of current machine.
|
// Returns logs of current machine.
|
||||||
@ -1309,7 +1309,7 @@ func (kl *Kubelet) ServeLogs(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run a command in a container, returns the combined stdout, stderr as an array of bytes
|
// Run a command in a container, returns the combined stdout, stderr as an array of bytes
|
||||||
func (kl *Kubelet) RunInContainer(podFullName, uuid, container string, cmd []string) ([]byte, error) {
|
func (kl *Kubelet) RunInContainer(podFullName string, uid util.UID, container string, cmd []string) ([]byte, error) {
|
||||||
if kl.runner == nil {
|
if kl.runner == nil {
|
||||||
return nil, fmt.Errorf("no runner specified.")
|
return nil, fmt.Errorf("no runner specified.")
|
||||||
}
|
}
|
||||||
@ -1317,7 +1317,7 @@ func (kl *Kubelet) RunInContainer(podFullName, uuid, container string, cmd []str
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uuid, container)
|
dockerContainer, found, _ := dockerContainers.FindPodContainer(podFullName, uid, container)
|
||||||
if !found {
|
if !found {
|
||||||
return nil, fmt.Errorf("container not found (%q)", container)
|
return nil, fmt.Errorf("container not found (%q)", container)
|
||||||
}
|
}
|
||||||
@ -1332,7 +1332,7 @@ func (kl *Kubelet) BirthCry() {
|
|||||||
ref := &api.ObjectReference{
|
ref := &api.ObjectReference{
|
||||||
Kind: "Minion",
|
Kind: "Minion",
|
||||||
Name: kl.hostname,
|
Name: kl.hostname,
|
||||||
UID: kl.hostname,
|
UID: util.UID(kl.hostname),
|
||||||
Namespace: api.NamespaceDefault,
|
Namespace: api.NamespaceDefault,
|
||||||
}
|
}
|
||||||
record.Eventf(ref, "", "starting", "Starting kubelet.")
|
record.Eventf(ref, "", "starting", "Starting kubelet.")
|
||||||
|
@ -807,7 +807,7 @@ func TestSyncPodDeletesDuplicate(t *testing.T) {
|
|||||||
|
|
||||||
type FalseHealthChecker struct{}
|
type FalseHealthChecker struct{}
|
||||||
|
|
||||||
func (f *FalseHealthChecker) HealthCheck(podFullName, podUUID string, status api.PodStatus, container api.Container) (health.Status, error) {
|
func (f *FalseHealthChecker) HealthCheck(podFullName string, podUID util.UID, status api.PodStatus, container api.Container) (health.Status, error) {
|
||||||
return health.Unhealthy, nil
|
return health.Unhealthy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/healthz"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/httplog"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
)
|
)
|
||||||
@ -61,13 +62,13 @@ func ListenAndServeKubeletServer(host HostInterface, address net.IP, port uint,
|
|||||||
// HostInterface contains all the kubelet methods required by the server.
|
// HostInterface contains all the kubelet methods required by the server.
|
||||||
// For testablitiy.
|
// For testablitiy.
|
||||||
type HostInterface interface {
|
type HostInterface interface {
|
||||||
GetContainerInfo(podFullName, uuid, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
GetContainerInfo(podFullName string, uid util.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||||
GetRootInfo(req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
GetRootInfo(req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||||
GetMachineInfo() (*info.MachineInfo, error)
|
GetMachineInfo() (*info.MachineInfo, error)
|
||||||
GetBoundPods() ([]api.BoundPod, error)
|
GetBoundPods() ([]api.BoundPod, error)
|
||||||
GetPodByName(namespace, name string) (*api.BoundPod, bool)
|
GetPodByName(namespace, name string) (*api.BoundPod, bool)
|
||||||
GetPodInfo(name, uuid string) (api.PodInfo, error)
|
GetPodInfo(name string, uid util.UID) (api.PodInfo, error)
|
||||||
RunInContainer(name, uuid, container string, cmd []string) ([]byte, error)
|
RunInContainer(name string, uid util.UID, container string, cmd []string) ([]byte, error)
|
||||||
GetKubeletContainerLogs(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error
|
GetKubeletContainerLogs(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error
|
||||||
ServeLogs(w http.ResponseWriter, req *http.Request)
|
ServeLogs(w http.ResponseWriter, req *http.Request)
|
||||||
}
|
}
|
||||||
@ -203,7 +204,7 @@ func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request, version
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
podID := u.Query().Get("podID")
|
podID := u.Query().Get("podID")
|
||||||
podUUID := u.Query().Get("UUID")
|
podUID := util.UID(u.Query().Get("UUID"))
|
||||||
podNamespace := u.Query().Get("podNamespace")
|
podNamespace := u.Query().Get("podNamespace")
|
||||||
if len(podID) == 0 {
|
if len(podID) == 0 {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
@ -220,7 +221,7 @@ func (s *Server) handlePodInfo(w http.ResponseWriter, req *http.Request, version
|
|||||||
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
info, err := s.host.GetPodInfo(GetPodFullName(pod), podUUID)
|
info, err := s.host.GetPodInfo(GetPodFullName(pod), podUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.error(w, err)
|
s.error(w, err)
|
||||||
return
|
return
|
||||||
@ -270,7 +271,8 @@ func (s *Server) handleRun(w http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
parts := strings.Split(u.Path, "/")
|
parts := strings.Split(u.Path, "/")
|
||||||
var podNamespace, podID, uuid, container string
|
var podNamespace, podID, container string
|
||||||
|
var uid util.UID
|
||||||
if len(parts) == 5 {
|
if len(parts) == 5 {
|
||||||
podNamespace = parts[2]
|
podNamespace = parts[2]
|
||||||
podID = parts[3]
|
podID = parts[3]
|
||||||
@ -278,7 +280,7 @@ func (s *Server) handleRun(w http.ResponseWriter, req *http.Request) {
|
|||||||
} else if len(parts) == 6 {
|
} else if len(parts) == 6 {
|
||||||
podNamespace = parts[2]
|
podNamespace = parts[2]
|
||||||
podID = parts[3]
|
podID = parts[3]
|
||||||
uuid = parts[4]
|
uid = util.UID(parts[4])
|
||||||
container = parts[5]
|
container = parts[5]
|
||||||
} else {
|
} else {
|
||||||
http.Error(w, "Unexpected path for command running", http.StatusBadRequest)
|
http.Error(w, "Unexpected path for command running", http.StatusBadRequest)
|
||||||
@ -290,7 +292,7 @@ func (s *Server) handleRun(w http.ResponseWriter, req *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
command := strings.Split(u.Query().Get("cmd"), " ")
|
command := strings.Split(u.Query().Get("cmd"), " ")
|
||||||
data, err := s.host.RunInContainer(GetPodFullName(pod), uuid, container, command)
|
data, err := s.host.RunInContainer(GetPodFullName(pod), uid, container, command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.error(w, err)
|
s.error(w, err)
|
||||||
return
|
return
|
||||||
@ -314,7 +316,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
// serveStats implements stats logic.
|
// serveStats implements stats logic.
|
||||||
func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) {
|
||||||
// /stats/<podfullname>/<containerName> or /stats/<namespace>/<podfullname>/<uuid>/<containerName>
|
// /stats/<podfullname>/<containerName> or /stats/<namespace>/<podfullname>/<uid>/<containerName>
|
||||||
components := strings.Split(strings.TrimPrefix(path.Clean(req.URL.Path), "/"), "/")
|
components := strings.Split(strings.TrimPrefix(path.Clean(req.URL.Path), "/"), "/")
|
||||||
var stats *info.ContainerInfo
|
var stats *info.ContainerInfo
|
||||||
var err error
|
var err error
|
||||||
@ -333,7 +335,7 @@ func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) {
|
|||||||
// TODO(monnand) Implement this
|
// TODO(monnand) Implement this
|
||||||
errors.New("pod level status currently unimplemented")
|
errors.New("pod level status currently unimplemented")
|
||||||
case 3:
|
case 3:
|
||||||
// Backward compatibility without uuid information, does not support namespace
|
// Backward compatibility without uid information, does not support namespace
|
||||||
pod, ok := s.host.GetPodByName(api.NamespaceDefault, components[1])
|
pod, ok := s.host.GetPodByName(api.NamespaceDefault, components[1])
|
||||||
if !ok {
|
if !ok {
|
||||||
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
||||||
@ -346,7 +348,7 @@ func (s *Server) serveStats(w http.ResponseWriter, req *http.Request) {
|
|||||||
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
http.Error(w, "Pod does not exist", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stats, err = s.host.GetContainerInfo(GetPodFullName(pod), components[3], components[4], &query)
|
stats, err = s.host.GetContainerInfo(GetPodFullName(pod), util.UID(components[3]), components[4], &query)
|
||||||
default:
|
default:
|
||||||
http.Error(w, "unknown resource.", http.StatusNotFound)
|
http.Error(w, "unknown resource.", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
|
@ -29,18 +29,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/google/cadvisor/info"
|
"github.com/google/cadvisor/info"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeKubelet struct {
|
type fakeKubelet struct {
|
||||||
podByNameFunc func(namespace, name string) (*api.BoundPod, bool)
|
podByNameFunc func(namespace, name string) (*api.BoundPod, bool)
|
||||||
infoFunc func(name string) (api.PodInfo, error)
|
infoFunc func(name string) (api.PodInfo, error)
|
||||||
containerInfoFunc func(podFullName, uid, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
containerInfoFunc func(podFullName string, uid util.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||||
rootInfoFunc func(query *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
rootInfoFunc func(query *info.ContainerInfoRequest) (*info.ContainerInfo, error)
|
||||||
machineInfoFunc func() (*info.MachineInfo, error)
|
machineInfoFunc func() (*info.MachineInfo, error)
|
||||||
boundPodsFunc func() ([]api.BoundPod, error)
|
boundPodsFunc func() ([]api.BoundPod, error)
|
||||||
logFunc func(w http.ResponseWriter, req *http.Request)
|
logFunc func(w http.ResponseWriter, req *http.Request)
|
||||||
runFunc func(podFullName, uuid, containerName string, cmd []string) ([]byte, error)
|
runFunc func(podFullName string, uid util.UID, containerName string, cmd []string) ([]byte, error)
|
||||||
containerLogsFunc func(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error
|
containerLogsFunc func(podFullName, containerName, tail string, follow bool, stdout, stderr io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,12 +49,12 @@ func (fk *fakeKubelet) GetPodByName(namespace, name string) (*api.BoundPod, bool
|
|||||||
return fk.podByNameFunc(namespace, name)
|
return fk.podByNameFunc(namespace, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fk *fakeKubelet) GetPodInfo(name, uuid string) (api.PodInfo, error) {
|
func (fk *fakeKubelet) GetPodInfo(name string, uid util.UID) (api.PodInfo, error) {
|
||||||
return fk.infoFunc(name)
|
return fk.infoFunc(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fk *fakeKubelet) GetContainerInfo(podFullName, uuid, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
func (fk *fakeKubelet) GetContainerInfo(podFullName string, uid util.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
return fk.containerInfoFunc(podFullName, uuid, containerName, req)
|
return fk.containerInfoFunc(podFullName, uid, containerName, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fk *fakeKubelet) GetRootInfo(req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
func (fk *fakeKubelet) GetRootInfo(req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
@ -76,8 +77,8 @@ func (fk *fakeKubelet) GetKubeletContainerLogs(podFullName, containerName, tail
|
|||||||
return fk.containerLogsFunc(podFullName, containerName, tail, follow, stdout, stderr)
|
return fk.containerLogsFunc(podFullName, containerName, tail, follow, stdout, stderr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fk *fakeKubelet) RunInContainer(podFullName, uuid, containerName string, cmd []string) ([]byte, error) {
|
func (fk *fakeKubelet) RunInContainer(podFullName string, uid util.UID, containerName string, cmd []string) ([]byte, error) {
|
||||||
return fk.runFunc(podFullName, uuid, containerName, cmd)
|
return fk.runFunc(podFullName, uid, containerName, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverTestFramework struct {
|
type serverTestFramework struct {
|
||||||
@ -161,7 +162,7 @@ func TestContainerInfo(t *testing.T) {
|
|||||||
podID := "somepod"
|
podID := "somepod"
|
||||||
expectedPodID := "somepod" + ".default.etcd"
|
expectedPodID := "somepod" + ".default.etcd"
|
||||||
expectedContainerName := "goodcontainer"
|
expectedContainerName := "goodcontainer"
|
||||||
fw.fakeKubelet.containerInfoFunc = func(podID, uid, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
fw.fakeKubelet.containerInfoFunc = func(podID string, uid util.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
if podID != expectedPodID || containerName != expectedContainerName {
|
if podID != expectedPodID || containerName != expectedContainerName {
|
||||||
return nil, fmt.Errorf("bad podID or containerName: podID=%v; containerName=%v", podID, containerName)
|
return nil, fmt.Errorf("bad podID or containerName: podID=%v; containerName=%v", podID, containerName)
|
||||||
}
|
}
|
||||||
@ -191,8 +192,8 @@ func TestContainerInfoWithUidNamespace(t *testing.T) {
|
|||||||
expectedPodID := "somepod" + "." + expectedNamespace + ".etcd"
|
expectedPodID := "somepod" + "." + expectedNamespace + ".etcd"
|
||||||
expectedContainerName := "goodcontainer"
|
expectedContainerName := "goodcontainer"
|
||||||
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
expectedUid := "9b01b80f-8fb4-11e4-95ab-4200af06647"
|
||||||
fw.fakeKubelet.containerInfoFunc = func(podID, uid, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
fw.fakeKubelet.containerInfoFunc = func(podID string, uid util.UID, containerName string, req *info.ContainerInfoRequest) (*info.ContainerInfo, error) {
|
||||||
if podID != expectedPodID || uid != expectedUid || containerName != expectedContainerName {
|
if podID != expectedPodID || string(uid) != expectedUid || containerName != expectedContainerName {
|
||||||
return nil, fmt.Errorf("bad podID or uid or containerName: podID=%v; uid=%v; containerName=%v", podID, uid, containerName)
|
return nil, fmt.Errorf("bad podID or uid or containerName: podID=%v; uid=%v; containerName=%v", podID, uid, containerName)
|
||||||
}
|
}
|
||||||
return expectedInfo, nil
|
return expectedInfo, nil
|
||||||
@ -296,7 +297,7 @@ func TestServeRunInContainer(t *testing.T) {
|
|||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedCommand := "ls -a"
|
expectedCommand := "ls -a"
|
||||||
fw.fakeKubelet.runFunc = func(podFullName, uuid, containerName string, cmd []string) ([]byte, error) {
|
fw.fakeKubelet.runFunc = func(podFullName string, uid util.UID, containerName string, cmd []string) ([]byte, error) {
|
||||||
if podFullName != expectedPodName {
|
if podFullName != expectedPodName {
|
||||||
t.Errorf("expected %s, got %s", expectedPodName, podFullName)
|
t.Errorf("expected %s, got %s", expectedPodName, podFullName)
|
||||||
}
|
}
|
||||||
@ -328,21 +329,21 @@ func TestServeRunInContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServeRunInContainerWithUUID(t *testing.T) {
|
func TestServeRunInContainerWithUID(t *testing.T) {
|
||||||
fw := newServerTest()
|
fw := newServerTest()
|
||||||
output := "foo bar"
|
output := "foo bar"
|
||||||
podNamespace := "other"
|
podNamespace := "other"
|
||||||
podName := "foo"
|
podName := "foo"
|
||||||
expectedPodName := podName + "." + podNamespace + ".etcd"
|
expectedPodName := podName + "." + podNamespace + ".etcd"
|
||||||
expectedUuid := "7e00838d_-_3523_-_11e4_-_8421_-_42010af0a720"
|
expectedUID := "7e00838d_-_3523_-_11e4_-_8421_-_42010af0a720"
|
||||||
expectedContainerName := "baz"
|
expectedContainerName := "baz"
|
||||||
expectedCommand := "ls -a"
|
expectedCommand := "ls -a"
|
||||||
fw.fakeKubelet.runFunc = func(podFullName, uuid, containerName string, cmd []string) ([]byte, error) {
|
fw.fakeKubelet.runFunc = func(podFullName string, uid util.UID, containerName string, cmd []string) ([]byte, error) {
|
||||||
if podFullName != expectedPodName {
|
if podFullName != expectedPodName {
|
||||||
t.Errorf("expected %s, got %s", expectedPodName, podFullName)
|
t.Errorf("expected %s, got %s", expectedPodName, podFullName)
|
||||||
}
|
}
|
||||||
if uuid != expectedUuid {
|
if string(uid) != expectedUID {
|
||||||
t.Errorf("expected %s, got %s", expectedUuid, uuid)
|
t.Errorf("expected %s, got %s", expectedUID, uid)
|
||||||
}
|
}
|
||||||
if containerName != expectedContainerName {
|
if containerName != expectedContainerName {
|
||||||
t.Errorf("expected %s, got %s", expectedContainerName, containerName)
|
t.Errorf("expected %s, got %s", expectedContainerName, containerName)
|
||||||
@ -354,7 +355,7 @@ func TestServeRunInContainerWithUUID(t *testing.T) {
|
|||||||
return []byte(output), nil
|
return []byte(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := http.Get(fw.testHTTPServer.URL + "/run/" + podNamespace + "/" + podName + "/" + expectedUuid + "/" + expectedContainerName + "?cmd=ls%20-a")
|
resp, err := http.Get(fw.testHTTPServer.URL + "/run/" + podNamespace + "/" + podName + "/" + expectedUID + "/" + expectedContainerName + "?cmd=ls%20-a")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Got error GETing: %v", err)
|
t.Fatalf("Got error GETing: %v", err)
|
||||||
|
@ -63,7 +63,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(controller.Name) == 0 {
|
if len(controller.Name) == 0 {
|
||||||
controller.Name = util.NewUUID().String()
|
controller.Name = string(util.NewUUID())
|
||||||
}
|
}
|
||||||
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
|
if errs := validation.ValidateReplicationController(controller); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("replicationController", controller.Name, errs)
|
return nil, errors.NewInvalid("replicationController", controller.Name, errs)
|
||||||
|
@ -102,7 +102,7 @@ func (rs *REST) getAttrs(obj runtime.Object) (objLabels, objFields labels.Set, e
|
|||||||
"involvedObject.kind": event.InvolvedObject.Kind,
|
"involvedObject.kind": event.InvolvedObject.Kind,
|
||||||
"involvedObject.namespace": event.InvolvedObject.Namespace,
|
"involvedObject.namespace": event.InvolvedObject.Namespace,
|
||||||
"involvedObject.name": event.InvolvedObject.Name,
|
"involvedObject.name": event.InvolvedObject.Name,
|
||||||
"involvedObject.uid": event.InvolvedObject.UID,
|
"involvedObject.uid": string(event.InvolvedObject.UID),
|
||||||
"involvedObject.apiVersion": event.InvolvedObject.APIVersion,
|
"involvedObject.apiVersion": event.InvolvedObject.APIVersion,
|
||||||
"involvedObject.resourceVersion": fmt.Sprintf("%s", event.InvolvedObject.ResourceVersion),
|
"involvedObject.resourceVersion": fmt.Sprintf("%s", event.InvolvedObject.ResourceVersion),
|
||||||
"involvedObject.fieldPath": event.InvolvedObject.FieldPath,
|
"involvedObject.fieldPath": event.InvolvedObject.FieldPath,
|
||||||
|
@ -62,7 +62,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE
|
|||||||
if len(pod.Name) == 0 {
|
if len(pod.Name) == 0 {
|
||||||
// TODO properly handle auto-generated names.
|
// TODO properly handle auto-generated names.
|
||||||
// See https://github.com/GoogleCloudPlatform/kubernetes/issues/148 170 & 1135
|
// See https://github.com/GoogleCloudPlatform/kubernetes/issues/148 170 & 1135
|
||||||
pod.Name = pod.UID
|
pod.Name = string(pod.UID)
|
||||||
}
|
}
|
||||||
if errs := validation.ValidatePod(pod); len(errs) > 0 {
|
if errs := validation.ValidatePod(pod); len(errs) > 0 {
|
||||||
return nil, errors.NewInvalid("pod", pod.Name, errs)
|
return nil, errors.NewInvalid("pod", pod.Name, errs)
|
||||||
|
@ -23,9 +23,10 @@ import (
|
|||||||
"code.google.com/p/go-uuid/uuid"
|
"code.google.com/p/go-uuid/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UUID interface {
|
// UID is a type that holds unique ID values, including UUIDs. Because we
|
||||||
String() string
|
// don't ONLY use UUIDs, this is an alias to string. Being a type captures
|
||||||
}
|
// intent and helps make sure that UIDs and names do not get conflated.
|
||||||
|
type UID string
|
||||||
|
|
||||||
var uuidLock sync.Mutex
|
var uuidLock sync.Mutex
|
||||||
|
|
||||||
@ -35,12 +36,12 @@ var uuidLock sync.Mutex
|
|||||||
* Blocks in a go routine, so that the caller doesn't have to wait.
|
* Blocks in a go routine, so that the caller doesn't have to wait.
|
||||||
* TODO: save old unused UUIDs so that no one has to block.
|
* TODO: save old unused UUIDs so that no one has to block.
|
||||||
*/
|
*/
|
||||||
func NewUUID() UUID {
|
func NewUUID() UID {
|
||||||
uuidLock.Lock()
|
uuidLock.Lock()
|
||||||
result := uuid.NewUUID()
|
result := uuid.NewUUID()
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(200 * time.Nanosecond)
|
time.Sleep(200 * time.Nanosecond)
|
||||||
uuidLock.Unlock()
|
uuidLock.Unlock()
|
||||||
}()
|
}()
|
||||||
return result
|
return UID(result.String())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user