Commit 8a764c02 authored by Daniel Smith's avatar Daniel Smith

Merge pull request #3478 from thockin/uid_type

Use a strong type for UID fields
parents f07a5d1e e86d4cd3
...@@ -312,7 +312,7 @@ func TestKubeletSendsEvent(c *client.Client) bool { ...@@ -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 { ...@@ -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 ( ...@@ -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 ...@@ -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 { ...@@ -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 { ...@@ -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 ( ...@@ -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 { ...@@ -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) { ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 ( ...@@ -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 { ...@@ -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) { ...@@ -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 ( ...@@ -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 { ...@@ -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 ( ...@@ -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 { ...@@ -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 ( ...@@ -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 ( ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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 ( ...@@ -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 ...@@ -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 ...@@ -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 ( ...@@ -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 { ...@@ -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) { ...@@ -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 ( ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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 { ...@@ -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, ...@@ -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
......
...@@ -807,7 +807,7 @@ func TestSyncPodDeletesDuplicate(t *testing.T) { ...@@ -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 ( ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 ( ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ( ...@@ -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 ...@@ -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())
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment