diff --git a/pkg/registry/controller/rest.go b/pkg/registry/controller/rest.go index 61310d749c9..591b239e5b5 100644 --- a/pkg/registry/controller/rest.go +++ b/pkg/registry/controller/rest.go @@ -28,8 +28,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" - - "code.google.com/p/go-uuid/uuid" ) // PodLister is anything that knows how to list pods. @@ -64,7 +62,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE } if len(controller.Name) == 0 { - controller.Name = uuid.NewUUID().String() + controller.Name = util.NewUUID().String() } // Pod Manifest ID should be assigned by the pod API controller.DesiredState.PodTemplate.DesiredState.Manifest.ID = "" diff --git a/pkg/registry/pod/rest.go b/pkg/registry/pod/rest.go index 04075ef1222..df0dac71026 100644 --- a/pkg/registry/pod/rest.go +++ b/pkg/registry/pod/rest.go @@ -32,7 +32,6 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/GoogleCloudPlatform/kubernetes/pkg/watch" - "code.google.com/p/go-uuid/uuid" "github.com/golang/glog" ) @@ -93,7 +92,7 @@ func (rs *REST) Create(ctx api.Context, obj runtime.Object) (<-chan apiserver.RE if !api.ValidNamespace(ctx, &pod.ObjectMeta) { return nil, errors.NewConflict("pod", pod.Namespace, fmt.Errorf("Pod.Namespace does not match the provided context")) } - pod.DesiredState.Manifest.UUID = uuid.NewUUID().String() + pod.DesiredState.Manifest.UUID = util.NewUUID().String() if len(pod.Name) == 0 { pod.Name = pod.DesiredState.Manifest.UUID } diff --git a/pkg/util/uuid.go b/pkg/util/uuid.go new file mode 100644 index 00000000000..bfd01b22ba4 --- /dev/null +++ b/pkg/util/uuid.go @@ -0,0 +1,46 @@ +/* +Copyright 2014 Google Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package util + +import ( + "sync" + "time" + + "code.google.com/p/go-uuid/uuid" +) + +type UUID interface { + String() string +} + +var uuidLock sync.Mutex + +/** + * The UUID package is naive and can generate identical UUIDs if the time interval is quick enough. + * Block subsequent UUIDs for 200 Nanoseconds, the UUID uses 100 ns increments, we block for 200 to be safe + * 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. + */ +func NewUUID() UUID { + uuidLock.Lock() + result := uuid.NewUUID() + go func() { + time.Sleep(200 * time.Nanosecond) + uuidLock.Unlock() + }() + return result +}