Replace uuid dependency with internal library
Signed-off-by: Stephen J Day <stephen.day@docker.com>master
							parent
							
								
									2317f721a3
								
							
						
					
					
						commit
						36e34a55ad
					
				|  | @ -5,11 +5,6 @@ | ||||||
| 		"./..." | 		"./..." | ||||||
| 	], | 	], | ||||||
| 	"Deps": [ | 	"Deps": [ | ||||||
| 		{ |  | ||||||
| 			"ImportPath": "code.google.com/p/go-uuid/uuid", |  | ||||||
| 			"Comment": "null-15", |  | ||||||
| 			"Rev": "35bc42037350f0078e3c974c6ea690f1926603ab" |  | ||||||
| 		}, |  | ||||||
| 		{ | 		{ | ||||||
| 			"ImportPath": "github.com/AdRoll/goamz/aws", | 			"ImportPath": "github.com/AdRoll/goamz/aws", | ||||||
| 			"Rev": "cc210f45dcb9889c2769a274522be2bf70edfb99" | 			"Rev": "cc210f45dcb9889c2769a274522be2bf70edfb99" | ||||||
|  |  | ||||||
|  | @ -1,27 +0,0 @@ | ||||||
| Copyright (c) 2009,2014 Google Inc. All rights reserved. |  | ||||||
| 
 |  | ||||||
| Redistribution and use in source and binary forms, with or without |  | ||||||
| modification, are permitted provided that the following conditions are |  | ||||||
| met: |  | ||||||
| 
 |  | ||||||
|    * Redistributions of source code must retain the above copyright |  | ||||||
| notice, this list of conditions and the following disclaimer. |  | ||||||
|    * Redistributions in binary form must reproduce the above |  | ||||||
| copyright notice, this list of conditions and the following disclaimer |  | ||||||
| in the documentation and/or other materials provided with the |  | ||||||
| distribution. |  | ||||||
|    * Neither the name of Google Inc. nor the names of its |  | ||||||
| contributors may be used to endorse or promote products derived from |  | ||||||
| this software without specific prior written permission. |  | ||||||
| 
 |  | ||||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |  | ||||||
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |  | ||||||
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |  | ||||||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |  | ||||||
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |  | ||||||
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |  | ||||||
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |  | ||||||
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |  | ||||||
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |  | ||||||
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |  | ||||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  | @ -1,84 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"fmt" |  | ||||||
| 	"os" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // A Domain represents a Version 2 domain
 |  | ||||||
| type Domain byte |  | ||||||
| 
 |  | ||||||
| // Domain constants for DCE Security (Version 2) UUIDs.
 |  | ||||||
| const ( |  | ||||||
| 	Person = Domain(0) |  | ||||||
| 	Group  = Domain(1) |  | ||||||
| 	Org    = Domain(2) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NewDCESecurity returns a DCE Security (Version 2) UUID.
 |  | ||||||
| //
 |  | ||||||
| // The domain should be one of Person, Group or Org.
 |  | ||||||
| // On a POSIX system the id should be the users UID for the Person
 |  | ||||||
| // domain and the users GID for the Group.  The meaning of id for
 |  | ||||||
| // the domain Org or on non-POSIX systems is site defined.
 |  | ||||||
| //
 |  | ||||||
| // For a given domain/id pair the same token may be returned for up to
 |  | ||||||
| // 7 minutes and 10 seconds.
 |  | ||||||
| func NewDCESecurity(domain Domain, id uint32) UUID { |  | ||||||
| 	uuid := NewUUID() |  | ||||||
| 	if uuid != nil { |  | ||||||
| 		uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2
 |  | ||||||
| 		uuid[9] = byte(domain) |  | ||||||
| 		binary.BigEndian.PutUint32(uuid[0:], id) |  | ||||||
| 	} |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewDCEPerson returns a DCE Security (Version 2) UUID in the person
 |  | ||||||
| // domain with the id returned by os.Getuid.
 |  | ||||||
| //
 |  | ||||||
| //  NewDCEPerson(Person, uint32(os.Getuid()))
 |  | ||||||
| func NewDCEPerson() UUID { |  | ||||||
| 	return NewDCESecurity(Person, uint32(os.Getuid())) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewDCEGroup returns a DCE Security (Version 2) UUID in the group
 |  | ||||||
| // domain with the id returned by os.Getgid.
 |  | ||||||
| //
 |  | ||||||
| //  NewDCEGroup(Group, uint32(os.Getgid()))
 |  | ||||||
| func NewDCEGroup() UUID { |  | ||||||
| 	return NewDCESecurity(Group, uint32(os.Getgid())) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Domain returns the domain for a Version 2 UUID or false.
 |  | ||||||
| func (uuid UUID) Domain() (Domain, bool) { |  | ||||||
| 	if v, _ := uuid.Version(); v != 2 { |  | ||||||
| 		return 0, false |  | ||||||
| 	} |  | ||||||
| 	return Domain(uuid[9]), true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Id returns the id for a Version 2 UUID or false.
 |  | ||||||
| func (uuid UUID) Id() (uint32, bool) { |  | ||||||
| 	if v, _ := uuid.Version(); v != 2 { |  | ||||||
| 		return 0, false |  | ||||||
| 	} |  | ||||||
| 	return binary.BigEndian.Uint32(uuid[0:4]), true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (d Domain) String() string { |  | ||||||
| 	switch d { |  | ||||||
| 	case Person: |  | ||||||
| 		return "Person" |  | ||||||
| 	case Group: |  | ||||||
| 		return "Group" |  | ||||||
| 	case Org: |  | ||||||
| 		return "Org" |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf("Domain%d", int(d)) |  | ||||||
| } |  | ||||||
|  | @ -1,8 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| // The uuid package generates and inspects UUIDs.
 |  | ||||||
| //
 |  | ||||||
| // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services.
 |  | ||||||
| package uuid |  | ||||||
|  | @ -1,53 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"crypto/md5" |  | ||||||
| 	"crypto/sha1" |  | ||||||
| 	"hash" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Well known Name Space IDs and UUIDs
 |  | ||||||
| var ( |  | ||||||
| 	NameSpace_DNS  = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") |  | ||||||
| 	NameSpace_URL  = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") |  | ||||||
| 	NameSpace_OID  = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") |  | ||||||
| 	NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") |  | ||||||
| 	NIL            = Parse("00000000-0000-0000-0000-000000000000") |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NewHash returns a new UUID dervied from the hash of space concatenated with
 |  | ||||||
| // data generated by h.  The hash should be at least 16 byte in length.  The
 |  | ||||||
| // first 16 bytes of the hash are used to form the UUID.  The version of the
 |  | ||||||
| // UUID will be the lower 4 bits of version.  NewHash is used to implement
 |  | ||||||
| // NewMD5 and NewSHA1.
 |  | ||||||
| func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { |  | ||||||
| 	h.Reset() |  | ||||||
| 	h.Write(space) |  | ||||||
| 	h.Write([]byte(data)) |  | ||||||
| 	s := h.Sum(nil) |  | ||||||
| 	uuid := make([]byte, 16) |  | ||||||
| 	copy(uuid, s) |  | ||||||
| 	uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) |  | ||||||
| 	uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant
 |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewMD5 returns a new MD5 (Version 3) UUID based on the
 |  | ||||||
| // supplied name space and data.
 |  | ||||||
| //
 |  | ||||||
| //  NewHash(md5.New(), space, data, 3)
 |  | ||||||
| func NewMD5(space UUID, data []byte) UUID { |  | ||||||
| 	return NewHash(md5.New(), space, data, 3) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NewSHA1 returns a new SHA1 (Version 5) UUID based on the
 |  | ||||||
| // supplied name space and data.
 |  | ||||||
| //
 |  | ||||||
| //  NewHash(sha1.New(), space, data, 5)
 |  | ||||||
| func NewSHA1(space UUID, data []byte) UUID { |  | ||||||
| 	return NewHash(sha1.New(), space, data, 5) |  | ||||||
| } |  | ||||||
|  | @ -1,30 +0,0 @@ | ||||||
| // Copyright 2014 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import "errors" |  | ||||||
| 
 |  | ||||||
| func (u UUID) MarshalJSON() ([]byte, error) { |  | ||||||
| 	if len(u) == 0 { |  | ||||||
| 		return []byte(`""`), nil |  | ||||||
| 	} |  | ||||||
| 	return []byte(`"` + u.String() + `"`), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (u *UUID) UnmarshalJSON(data []byte) error { |  | ||||||
| 	if len(data) == 0 || string(data) == `""` { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { |  | ||||||
| 		return errors.New("invalid UUID format") |  | ||||||
| 	} |  | ||||||
| 	data = data[1 : len(data)-1] |  | ||||||
| 	uu := Parse(string(data)) |  | ||||||
| 	if uu == nil { |  | ||||||
| 		return errors.New("invalid UUID format") |  | ||||||
| 	} |  | ||||||
| 	*u = uu |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  | @ -1,32 +0,0 @@ | ||||||
| // Copyright 2014 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"encoding/json" |  | ||||||
| 	"reflect" |  | ||||||
| 	"testing" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") |  | ||||||
| 
 |  | ||||||
| func TestJSON(t *testing.T) { |  | ||||||
| 	type S struct { |  | ||||||
| 		ID1 UUID |  | ||||||
| 		ID2 UUID |  | ||||||
| 	} |  | ||||||
| 	s1 := S{ID1: testUUID} |  | ||||||
| 	data, err := json.Marshal(&s1) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	var s2 S |  | ||||||
| 	if err := json.Unmarshal(data, &s2); err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if !reflect.DeepEqual(&s1, &s2) { |  | ||||||
| 		t.Errorf("got %#v, want %#v", s2, s1) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,101 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import "net" |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	interfaces []net.Interface // cached list of interfaces
 |  | ||||||
| 	ifname     string          // name of interface being used
 |  | ||||||
| 	nodeID     []byte          // hardware for version 1 UUIDs
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NodeInterface returns the name of the interface from which the NodeID was
 |  | ||||||
| // derived.  The interface "user" is returned if the NodeID was set by
 |  | ||||||
| // SetNodeID.
 |  | ||||||
| func NodeInterface() string { |  | ||||||
| 	return ifname |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.
 |  | ||||||
| // If name is "" then the first usable interface found will be used or a random
 |  | ||||||
| // Node ID will be generated.  If a named interface cannot be found then false
 |  | ||||||
| // is returned.
 |  | ||||||
| //
 |  | ||||||
| // SetNodeInterface never fails when name is "".
 |  | ||||||
| func SetNodeInterface(name string) bool { |  | ||||||
| 	if interfaces == nil { |  | ||||||
| 		var err error |  | ||||||
| 		interfaces, err = net.Interfaces() |  | ||||||
| 		if err != nil && name != "" { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for _, ifs := range interfaces { |  | ||||||
| 		if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { |  | ||||||
| 			if setNodeID(ifs.HardwareAddr) { |  | ||||||
| 				ifname = ifs.Name |  | ||||||
| 				return true |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	// We found no interfaces with a valid hardware address.  If name
 |  | ||||||
| 	// does not specify a specific interface generate a random Node ID
 |  | ||||||
| 	// (section 4.1.6)
 |  | ||||||
| 	if name == "" { |  | ||||||
| 		if nodeID == nil { |  | ||||||
| 			nodeID = make([]byte, 6) |  | ||||||
| 		} |  | ||||||
| 		randomBits(nodeID) |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NodeID returns a slice of a copy of the current Node ID, setting the Node ID
 |  | ||||||
| // if not already set.
 |  | ||||||
| func NodeID() []byte { |  | ||||||
| 	if nodeID == nil { |  | ||||||
| 		SetNodeInterface("") |  | ||||||
| 	} |  | ||||||
| 	nid := make([]byte, 6) |  | ||||||
| 	copy(nid, nodeID) |  | ||||||
| 	return nid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetNodeID sets the Node ID to be used for Version 1 UUIDs.  The first 6 bytes
 |  | ||||||
| // of id are used.  If id is less than 6 bytes then false is returned and the
 |  | ||||||
| // Node ID is not set.
 |  | ||||||
| func SetNodeID(id []byte) bool { |  | ||||||
| 	if setNodeID(id) { |  | ||||||
| 		ifname = "user" |  | ||||||
| 		return true |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func setNodeID(id []byte) bool { |  | ||||||
| 	if len(id) < 6 { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	if nodeID == nil { |  | ||||||
| 		nodeID = make([]byte, 6) |  | ||||||
| 	} |  | ||||||
| 	copy(nodeID, id) |  | ||||||
| 	return true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // NodeID returns the 6 byte node id encoded in uuid.  It returns nil if uuid is
 |  | ||||||
| // not valid.  The NodeID is only well defined for version 1 and 2 UUIDs.
 |  | ||||||
| func (uuid UUID) NodeID() []byte { |  | ||||||
| 	if len(uuid) != 16 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	node := make([]byte, 6) |  | ||||||
| 	copy(node, uuid[10:]) |  | ||||||
| 	return node |  | ||||||
| } |  | ||||||
|  | @ -1,66 +0,0 @@ | ||||||
| // Copyright 2014 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"flag" |  | ||||||
| 	"runtime" |  | ||||||
| 	"testing" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // This test is only run when --regressions is passed on the go test line.
 |  | ||||||
| var regressions = flag.Bool("regressions", false, "run uuid regression tests") |  | ||||||
| 
 |  | ||||||
| // TestClockSeqRace tests for a particular race condition of returning two
 |  | ||||||
| // identical Version1 UUIDs.  The duration of 1 minute was chosen as the race
 |  | ||||||
| // condition, before being fixed, nearly always occured in under 30 seconds.
 |  | ||||||
| func TestClockSeqRace(t *testing.T) { |  | ||||||
| 	if !*regressions { |  | ||||||
| 		t.Skip("skipping regression tests") |  | ||||||
| 	} |  | ||||||
| 	duration := time.Minute |  | ||||||
| 
 |  | ||||||
| 	done := make(chan struct{}) |  | ||||||
| 	defer close(done) |  | ||||||
| 
 |  | ||||||
| 	ch := make(chan UUID, 10000) |  | ||||||
| 	ncpu := runtime.NumCPU() |  | ||||||
| 	switch ncpu { |  | ||||||
| 	case 0, 1: |  | ||||||
| 		// We can't run the test effectively.
 |  | ||||||
| 		t.Skip("skipping race test, only one CPU detected") |  | ||||||
| 		return |  | ||||||
| 	default: |  | ||||||
| 		runtime.GOMAXPROCS(ncpu) |  | ||||||
| 	} |  | ||||||
| 	for i := 0; i < ncpu; i++ { |  | ||||||
| 		go func() { |  | ||||||
| 			for { |  | ||||||
| 				select { |  | ||||||
| 				case <-done: |  | ||||||
| 					return |  | ||||||
| 				case ch <- NewUUID(): |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		}() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	uuids := make(map[string]bool) |  | ||||||
| 	cnt := 0 |  | ||||||
| 	start := time.Now() |  | ||||||
| 	for u := range ch { |  | ||||||
| 		s := u.String() |  | ||||||
| 		if uuids[s] { |  | ||||||
| 			t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		uuids[s] = true |  | ||||||
| 		if time.Since(start) > duration { |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		cnt++ |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,132 +0,0 @@ | ||||||
| // Copyright 2014 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"encoding/binary" |  | ||||||
| 	"sync" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // A Time represents a time as the number of 100's of nanoseconds since 15 Oct
 |  | ||||||
| // 1582.
 |  | ||||||
| type Time int64 |  | ||||||
| 
 |  | ||||||
| const ( |  | ||||||
| 	lillian    = 2299160          // Julian day of 15 Oct 1582
 |  | ||||||
| 	unix       = 2440587          // Julian day of 1 Jan 1970
 |  | ||||||
| 	epoch      = unix - lillian   // Days between epochs
 |  | ||||||
| 	g1582      = epoch * 86400    // seconds between epochs
 |  | ||||||
| 	g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var ( |  | ||||||
| 	mu        sync.Mutex |  | ||||||
| 	lasttime  uint64 // last time we returned
 |  | ||||||
| 	clock_seq uint16 // clock sequence for this run
 |  | ||||||
| 
 |  | ||||||
| 	timeNow = time.Now // for testing
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // UnixTime converts t the number of seconds and nanoseconds using the Unix
 |  | ||||||
| // epoch of 1 Jan 1970.
 |  | ||||||
| func (t Time) UnixTime() (sec, nsec int64) { |  | ||||||
| 	sec = int64(t - g1582ns100) |  | ||||||
| 	nsec = (sec % 10000000) * 100 |  | ||||||
| 	sec /= 10000000 |  | ||||||
| 	return sec, nsec |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and
 |  | ||||||
| // clock sequence as well as adjusting the clock sequence as needed.  An error
 |  | ||||||
| // is returned if the current time cannot be determined.
 |  | ||||||
| func GetTime() (Time, uint16, error) { |  | ||||||
| 	defer mu.Unlock() |  | ||||||
| 	mu.Lock() |  | ||||||
| 	return getTime() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func getTime() (Time, uint16, error) { |  | ||||||
| 	t := timeNow() |  | ||||||
| 
 |  | ||||||
| 	// If we don't have a clock sequence already, set one.
 |  | ||||||
| 	if clock_seq == 0 { |  | ||||||
| 		setClockSequence(-1) |  | ||||||
| 	} |  | ||||||
| 	now := uint64(t.UnixNano()/100) + g1582ns100 |  | ||||||
| 
 |  | ||||||
| 	// If time has gone backwards with this clock sequence then we
 |  | ||||||
| 	// increment the clock sequence
 |  | ||||||
| 	if now <= lasttime { |  | ||||||
| 		clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000 |  | ||||||
| 	} |  | ||||||
| 	lasttime = now |  | ||||||
| 	return Time(now), clock_seq, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ClockSequence returns the current clock sequence, generating one if not
 |  | ||||||
| // already set.  The clock sequence is only used for Version 1 UUIDs.
 |  | ||||||
| //
 |  | ||||||
| // The uuid package does not use global static storage for the clock sequence or
 |  | ||||||
| // the last time a UUID was generated.  Unless SetClockSequence a new random
 |  | ||||||
| // clock sequence is generated the first time a clock sequence is requested by
 |  | ||||||
| // ClockSequence, GetTime, or NewUUID.  (section 4.2.1.1) sequence is generated
 |  | ||||||
| // for
 |  | ||||||
| func ClockSequence() int { |  | ||||||
| 	defer mu.Unlock() |  | ||||||
| 	mu.Lock() |  | ||||||
| 	return clockSequence() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func clockSequence() int { |  | ||||||
| 	if clock_seq == 0 { |  | ||||||
| 		setClockSequence(-1) |  | ||||||
| 	} |  | ||||||
| 	return int(clock_seq & 0x3fff) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetClockSeq sets the clock sequence to the lower 14 bits of seq.  Setting to
 |  | ||||||
| // -1 causes a new sequence to be generated.
 |  | ||||||
| func SetClockSequence(seq int) { |  | ||||||
| 	defer mu.Unlock() |  | ||||||
| 	mu.Lock() |  | ||||||
| 	setClockSequence(seq) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func setClockSequence(seq int) { |  | ||||||
| 	if seq == -1 { |  | ||||||
| 		var b [2]byte |  | ||||||
| 		randomBits(b[:]) // clock sequence
 |  | ||||||
| 		seq = int(b[0])<<8 | int(b[1]) |  | ||||||
| 	} |  | ||||||
| 	old_seq := clock_seq |  | ||||||
| 	clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant
 |  | ||||||
| 	if old_seq != clock_seq { |  | ||||||
| 		lasttime = 0 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in
 |  | ||||||
| // uuid.  It returns false if uuid is not valid.  The time is only well defined
 |  | ||||||
| // for version 1 and 2 UUIDs.
 |  | ||||||
| func (uuid UUID) Time() (Time, bool) { |  | ||||||
| 	if len(uuid) != 16 { |  | ||||||
| 		return 0, false |  | ||||||
| 	} |  | ||||||
| 	time := int64(binary.BigEndian.Uint32(uuid[0:4])) |  | ||||||
| 	time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 |  | ||||||
| 	time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 |  | ||||||
| 	return Time(time), true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ClockSequence returns the clock sequence encoded in uuid.  It returns false
 |  | ||||||
| // if uuid is not valid.  The clock sequence is only well defined for version 1
 |  | ||||||
| // and 2 UUIDs.
 |  | ||||||
| func (uuid UUID) ClockSequence() (int, bool) { |  | ||||||
| 	if len(uuid) != 16 { |  | ||||||
| 		return 0, false |  | ||||||
| 	} |  | ||||||
| 	return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true |  | ||||||
| } |  | ||||||
|  | @ -1,43 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // randomBits completely fills slice b with random data.
 |  | ||||||
| func randomBits(b []byte) { |  | ||||||
| 	if _, err := io.ReadFull(rander, b); err != nil { |  | ||||||
| 		panic(err.Error()) // rand should never fail
 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // xvalues returns the value of a byte as a hexadecimal digit or 255.
 |  | ||||||
| var xvalues = []byte{ |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| 	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // xtob converts the the first two hex bytes of x into a byte.
 |  | ||||||
| func xtob(x string) (byte, bool) { |  | ||||||
| 	b1 := xvalues[x[0]] |  | ||||||
| 	b2 := xvalues[x[1]] |  | ||||||
| 	return (b1 << 4) | b2, b1 != 255 && b2 != 255 |  | ||||||
| } |  | ||||||
|  | @ -1,163 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"crypto/rand" |  | ||||||
| 	"fmt" |  | ||||||
| 	"io" |  | ||||||
| 	"strings" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC
 |  | ||||||
| // 4122.
 |  | ||||||
| type UUID []byte |  | ||||||
| 
 |  | ||||||
| // A Version represents a UUIDs version.
 |  | ||||||
| type Version byte |  | ||||||
| 
 |  | ||||||
| // A Variant represents a UUIDs variant.
 |  | ||||||
| type Variant byte |  | ||||||
| 
 |  | ||||||
| // Constants returned by Variant.
 |  | ||||||
| const ( |  | ||||||
| 	Invalid   = Variant(iota) // Invalid UUID
 |  | ||||||
| 	RFC4122                   // The variant specified in RFC4122
 |  | ||||||
| 	Reserved                  // Reserved, NCS backward compatibility.
 |  | ||||||
| 	Microsoft                 // Reserved, Microsoft Corporation backward compatibility.
 |  | ||||||
| 	Future                    // Reserved for future definition.
 |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var rander = rand.Reader // random function
 |  | ||||||
| 
 |  | ||||||
| // New returns a new random (version 4) UUID as a string.  It is a convenience
 |  | ||||||
| // function for NewRandom().String().
 |  | ||||||
| func New() string { |  | ||||||
| 	return NewRandom().String() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Parse decodes s into a UUID or returns nil.  Both the UUID form of
 |  | ||||||
| // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and
 |  | ||||||
| // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded.
 |  | ||||||
| func Parse(s string) UUID { |  | ||||||
| 	if len(s) == 36+9 { |  | ||||||
| 		if strings.ToLower(s[:9]) != "urn:uuid:" { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		s = s[9:] |  | ||||||
| 	} else if len(s) != 36 { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 	uuid := make([]byte, 16) |  | ||||||
| 	for i, x := range []int{ |  | ||||||
| 		0, 2, 4, 6, |  | ||||||
| 		9, 11, |  | ||||||
| 		14, 16, |  | ||||||
| 		19, 21, |  | ||||||
| 		24, 26, 28, 30, 32, 34} { |  | ||||||
| 		if v, ok := xtob(s[x:]); !ok { |  | ||||||
| 			return nil |  | ||||||
| 		} else { |  | ||||||
| 			uuid[i] = v |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Equal returns true if uuid1 and uuid2 are equal.
 |  | ||||||
| func Equal(uuid1, uuid2 UUID) bool { |  | ||||||
| 	return bytes.Equal(uuid1, uuid2) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
 |  | ||||||
| // , or "" if uuid is invalid.
 |  | ||||||
| func (uuid UUID) String() string { |  | ||||||
| 	if uuid == nil || len(uuid) != 16 { |  | ||||||
| 		return "" |  | ||||||
| 	} |  | ||||||
| 	b := []byte(uuid) |  | ||||||
| 	return fmt.Sprintf("%08x-%04x-%04x-%04x-%012x", |  | ||||||
| 		b[:4], b[4:6], b[6:8], b[8:10], b[10:]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // URN returns the RFC 2141 URN form of uuid,
 |  | ||||||
| // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,  or "" if uuid is invalid.
 |  | ||||||
| func (uuid UUID) URN() string { |  | ||||||
| 	if uuid == nil || len(uuid) != 16 { |  | ||||||
| 		return "" |  | ||||||
| 	} |  | ||||||
| 	b := []byte(uuid) |  | ||||||
| 	return fmt.Sprintf("urn:uuid:%08x-%04x-%04x-%04x-%012x", |  | ||||||
| 		b[:4], b[4:6], b[6:8], b[8:10], b[10:]) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Variant returns the variant encoded in uuid.  It returns Invalid if
 |  | ||||||
| // uuid is invalid.
 |  | ||||||
| func (uuid UUID) Variant() Variant { |  | ||||||
| 	if len(uuid) != 16 { |  | ||||||
| 		return Invalid |  | ||||||
| 	} |  | ||||||
| 	switch { |  | ||||||
| 	case (uuid[8] & 0xc0) == 0x80: |  | ||||||
| 		return RFC4122 |  | ||||||
| 	case (uuid[8] & 0xe0) == 0xc0: |  | ||||||
| 		return Microsoft |  | ||||||
| 	case (uuid[8] & 0xe0) == 0xe0: |  | ||||||
| 		return Future |  | ||||||
| 	default: |  | ||||||
| 		return Reserved |  | ||||||
| 	} |  | ||||||
| 	panic("unreachable") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Version returns the verison of uuid.  It returns false if uuid is not
 |  | ||||||
| // valid.
 |  | ||||||
| func (uuid UUID) Version() (Version, bool) { |  | ||||||
| 	if len(uuid) != 16 { |  | ||||||
| 		return 0, false |  | ||||||
| 	} |  | ||||||
| 	return Version(uuid[6] >> 4), true |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (v Version) String() string { |  | ||||||
| 	if v > 15 { |  | ||||||
| 		return fmt.Sprintf("BAD_VERSION_%d", v) |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf("VERSION_%d", v) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (v Variant) String() string { |  | ||||||
| 	switch v { |  | ||||||
| 	case RFC4122: |  | ||||||
| 		return "RFC4122" |  | ||||||
| 	case Reserved: |  | ||||||
| 		return "Reserved" |  | ||||||
| 	case Microsoft: |  | ||||||
| 		return "Microsoft" |  | ||||||
| 	case Future: |  | ||||||
| 		return "Future" |  | ||||||
| 	case Invalid: |  | ||||||
| 		return "Invalid" |  | ||||||
| 	} |  | ||||||
| 	return fmt.Sprintf("BadVariant%d", int(v)) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetRand sets the random number generator to r, which implents io.Reader.
 |  | ||||||
| // If r.Read returns an error when the package requests random data then
 |  | ||||||
| // a panic will be issued.
 |  | ||||||
| //
 |  | ||||||
| // Calling SetRand with nil sets the random number generator to the default
 |  | ||||||
| // generator.
 |  | ||||||
| func SetRand(r io.Reader) { |  | ||||||
| 	if r == nil { |  | ||||||
| 		rander = rand.Reader |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	rander = r |  | ||||||
| } |  | ||||||
|  | @ -1,390 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" |  | ||||||
| 	"os" |  | ||||||
| 	"strings" |  | ||||||
| 	"testing" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| type test struct { |  | ||||||
| 	in      string |  | ||||||
| 	version Version |  | ||||||
| 	variant Variant |  | ||||||
| 	isuuid  bool |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var tests = []test{ |  | ||||||
| 	{"f47ac10b-58cc-0372-8567-0e02b2c3d479", 0, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-1372-8567-0e02b2c3d479", 1, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-2372-8567-0e02b2c3d479", 2, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-3372-8567-0e02b2c3d479", 3, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-5372-8567-0e02b2c3d479", 5, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-6372-8567-0e02b2c3d479", 6, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-7372-8567-0e02b2c3d479", 7, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-8372-8567-0e02b2c3d479", 8, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-9372-8567-0e02b2c3d479", 9, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-a372-8567-0e02b2c3d479", 10, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-b372-8567-0e02b2c3d479", 11, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-c372-8567-0e02b2c3d479", 12, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-d372-8567-0e02b2c3d479", 13, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-e372-8567-0e02b2c3d479", 14, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-f372-8567-0e02b2c3d479", 15, RFC4122, true}, |  | ||||||
| 
 |  | ||||||
| 	{"urn:uuid:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"URN:UUID:f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-0567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-1567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-2567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-3567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-4567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-5567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-6567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-7567-0e02b2c3d479", 4, Reserved, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-8567-0e02b2c3d479", 4, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-9567-0e02b2c3d479", 4, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-a567-0e02b2c3d479", 4, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-b567-0e02b2c3d479", 4, RFC4122, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-c567-0e02b2c3d479", 4, Microsoft, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-d567-0e02b2c3d479", 4, Microsoft, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-e567-0e02b2c3d479", 4, Future, true}, |  | ||||||
| 	{"f47ac10b-58cc-4372-f567-0e02b2c3d479", 4, Future, true}, |  | ||||||
| 
 |  | ||||||
| 	{"f47ac10b158cc-5372-a567-0e02b2c3d479", 0, Invalid, false}, |  | ||||||
| 	{"f47ac10b-58cc25372-a567-0e02b2c3d479", 0, Invalid, false}, |  | ||||||
| 	{"f47ac10b-58cc-53723a567-0e02b2c3d479", 0, Invalid, false}, |  | ||||||
| 	{"f47ac10b-58cc-5372-a56740e02b2c3d479", 0, Invalid, false}, |  | ||||||
| 	{"f47ac10b-58cc-5372-a567-0e02-2c3d479", 0, Invalid, false}, |  | ||||||
| 	{"g47ac10b-58cc-4372-a567-0e02b2c3d479", 0, Invalid, false}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| var constants = []struct { |  | ||||||
| 	c    interface{} |  | ||||||
| 	name string |  | ||||||
| }{ |  | ||||||
| 	{Person, "Person"}, |  | ||||||
| 	{Group, "Group"}, |  | ||||||
| 	{Org, "Org"}, |  | ||||||
| 	{Invalid, "Invalid"}, |  | ||||||
| 	{RFC4122, "RFC4122"}, |  | ||||||
| 	{Reserved, "Reserved"}, |  | ||||||
| 	{Microsoft, "Microsoft"}, |  | ||||||
| 	{Future, "Future"}, |  | ||||||
| 	{Domain(17), "Domain17"}, |  | ||||||
| 	{Variant(42), "BadVariant42"}, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func testTest(t *testing.T, in string, tt test) { |  | ||||||
| 	uuid := Parse(in) |  | ||||||
| 	if ok := (uuid != nil); ok != tt.isuuid { |  | ||||||
| 		t.Errorf("Parse(%s) got %v expected %v\b", in, ok, tt.isuuid) |  | ||||||
| 	} |  | ||||||
| 	if uuid == nil { |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if v := uuid.Variant(); v != tt.variant { |  | ||||||
| 		t.Errorf("Variant(%s) got %d expected %d\b", in, v, tt.variant) |  | ||||||
| 	} |  | ||||||
| 	if v, _ := uuid.Version(); v != tt.version { |  | ||||||
| 		t.Errorf("Version(%s) got %d expected %d\b", in, v, tt.version) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestUUID(t *testing.T) { |  | ||||||
| 	for _, tt := range tests { |  | ||||||
| 		testTest(t, tt.in, tt) |  | ||||||
| 		testTest(t, strings.ToUpper(tt.in), tt) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestConstants(t *testing.T) { |  | ||||||
| 	for x, tt := range constants { |  | ||||||
| 		v, ok := tt.c.(fmt.Stringer) |  | ||||||
| 		if !ok { |  | ||||||
| 			t.Errorf("%x: %v: not a stringer", x, v) |  | ||||||
| 		} else if s := v.String(); s != tt.name { |  | ||||||
| 			v, _ := tt.c.(int) |  | ||||||
| 			t.Errorf("%x: Constant %T:%d gives %q, expected %q\n", x, tt.c, v, s, tt.name) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestRandomUUID(t *testing.T) { |  | ||||||
| 	m := make(map[string]bool) |  | ||||||
| 	for x := 1; x < 32; x++ { |  | ||||||
| 		uuid := NewRandom() |  | ||||||
| 		s := uuid.String() |  | ||||||
| 		if m[s] { |  | ||||||
| 			t.Errorf("NewRandom returned duplicated UUID %s\n", s) |  | ||||||
| 		} |  | ||||||
| 		m[s] = true |  | ||||||
| 		if v, _ := uuid.Version(); v != 4 { |  | ||||||
| 			t.Errorf("Random UUID of version %s\n", v) |  | ||||||
| 		} |  | ||||||
| 		if uuid.Variant() != RFC4122 { |  | ||||||
| 			t.Errorf("Random UUID is variant %d\n", uuid.Variant()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestNew(t *testing.T) { |  | ||||||
| 	m := make(map[string]bool) |  | ||||||
| 	for x := 1; x < 32; x++ { |  | ||||||
| 		s := New() |  | ||||||
| 		if m[s] { |  | ||||||
| 			t.Errorf("New returned duplicated UUID %s\n", s) |  | ||||||
| 		} |  | ||||||
| 		m[s] = true |  | ||||||
| 		uuid := Parse(s) |  | ||||||
| 		if uuid == nil { |  | ||||||
| 			t.Errorf("New returned %q which does not decode\n", s) |  | ||||||
| 			continue |  | ||||||
| 		} |  | ||||||
| 		if v, _ := uuid.Version(); v != 4 { |  | ||||||
| 			t.Errorf("Random UUID of version %s\n", v) |  | ||||||
| 		} |  | ||||||
| 		if uuid.Variant() != RFC4122 { |  | ||||||
| 			t.Errorf("Random UUID is variant %d\n", uuid.Variant()) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func clockSeq(t *testing.T, uuid UUID) int { |  | ||||||
| 	seq, ok := uuid.ClockSequence() |  | ||||||
| 	if !ok { |  | ||||||
| 		t.Fatalf("%s: invalid clock sequence\n", uuid) |  | ||||||
| 	} |  | ||||||
| 	return seq |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestClockSeq(t *testing.T) { |  | ||||||
| 	// Fake time.Now for this test to return a monotonically advancing time; restore it at end.
 |  | ||||||
| 	defer func(orig func() time.Time) { timeNow = orig }(timeNow) |  | ||||||
| 	monTime := time.Now() |  | ||||||
| 	timeNow = func() time.Time { |  | ||||||
| 		monTime = monTime.Add(1 * time.Second) |  | ||||||
| 		return monTime |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SetClockSequence(-1) |  | ||||||
| 	uuid1 := NewUUID() |  | ||||||
| 	uuid2 := NewUUID() |  | ||||||
| 
 |  | ||||||
| 	if clockSeq(t, uuid1) != clockSeq(t, uuid2) { |  | ||||||
| 		t.Errorf("clock sequence %d != %d\n", clockSeq(t, uuid1), clockSeq(t, uuid2)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SetClockSequence(-1) |  | ||||||
| 	uuid2 = NewUUID() |  | ||||||
| 
 |  | ||||||
| 	// Just on the very off chance we generated the same sequence
 |  | ||||||
| 	// two times we try again.
 |  | ||||||
| 	if clockSeq(t, uuid1) == clockSeq(t, uuid2) { |  | ||||||
| 		SetClockSequence(-1) |  | ||||||
| 		uuid2 = NewUUID() |  | ||||||
| 	} |  | ||||||
| 	if clockSeq(t, uuid1) == clockSeq(t, uuid2) { |  | ||||||
| 		t.Errorf("Duplicate clock sequence %d\n", clockSeq(t, uuid1)) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	SetClockSequence(0x1234) |  | ||||||
| 	uuid1 = NewUUID() |  | ||||||
| 	if seq := clockSeq(t, uuid1); seq != 0x1234 { |  | ||||||
| 		t.Errorf("%s: expected seq 0x1234 got 0x%04x\n", uuid1, seq) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestCoding(t *testing.T) { |  | ||||||
| 	text := "7d444840-9dc0-11d1-b245-5ffdce74fad2" |  | ||||||
| 	urn := "urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2" |  | ||||||
| 	data := UUID{ |  | ||||||
| 		0x7d, 0x44, 0x48, 0x40, |  | ||||||
| 		0x9d, 0xc0, |  | ||||||
| 		0x11, 0xd1, |  | ||||||
| 		0xb2, 0x45, |  | ||||||
| 		0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2, |  | ||||||
| 	} |  | ||||||
| 	if v := data.String(); v != text { |  | ||||||
| 		t.Errorf("%x: encoded to %s, expected %s\n", data, v, text) |  | ||||||
| 	} |  | ||||||
| 	if v := data.URN(); v != urn { |  | ||||||
| 		t.Errorf("%x: urn is %s, expected %s\n", data, v, urn) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	uuid := Parse(text) |  | ||||||
| 	if !Equal(uuid, data) { |  | ||||||
| 		t.Errorf("%s: decoded to %s, expected %s\n", text, uuid, data) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestVersion1(t *testing.T) { |  | ||||||
| 	uuid1 := NewUUID() |  | ||||||
| 	uuid2 := NewUUID() |  | ||||||
| 
 |  | ||||||
| 	if Equal(uuid1, uuid2) { |  | ||||||
| 		t.Errorf("%s:duplicate uuid\n", uuid1) |  | ||||||
| 	} |  | ||||||
| 	if v, _ := uuid1.Version(); v != 1 { |  | ||||||
| 		t.Errorf("%s: version %s expected 1\n", uuid1, v) |  | ||||||
| 	} |  | ||||||
| 	if v, _ := uuid2.Version(); v != 1 { |  | ||||||
| 		t.Errorf("%s: version %s expected 1\n", uuid2, v) |  | ||||||
| 	} |  | ||||||
| 	n1 := uuid1.NodeID() |  | ||||||
| 	n2 := uuid2.NodeID() |  | ||||||
| 	if !bytes.Equal(n1, n2) { |  | ||||||
| 		t.Errorf("Different nodes %x != %x\n", n1, n2) |  | ||||||
| 	} |  | ||||||
| 	t1, ok := uuid1.Time() |  | ||||||
| 	if !ok { |  | ||||||
| 		t.Errorf("%s: invalid time\n", uuid1) |  | ||||||
| 	} |  | ||||||
| 	t2, ok := uuid2.Time() |  | ||||||
| 	if !ok { |  | ||||||
| 		t.Errorf("%s: invalid time\n", uuid2) |  | ||||||
| 	} |  | ||||||
| 	q1, ok := uuid1.ClockSequence() |  | ||||||
| 	if !ok { |  | ||||||
| 		t.Errorf("%s: invalid clock sequence\n", uuid1) |  | ||||||
| 	} |  | ||||||
| 	q2, ok := uuid2.ClockSequence() |  | ||||||
| 	if !ok { |  | ||||||
| 		t.Errorf("%s: invalid clock sequence", uuid2) |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	switch { |  | ||||||
| 	case t1 == t2 && q1 == q2: |  | ||||||
| 		t.Errorf("time stopped\n") |  | ||||||
| 	case t1 > t2 && q1 == q2: |  | ||||||
| 		t.Errorf("time reversed\n") |  | ||||||
| 	case t1 < t2 && q1 != q2: |  | ||||||
| 		t.Errorf("clock sequence chaned unexpectedly\n") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestNodeAndTime(t *testing.T) { |  | ||||||
| 	// Time is February 5, 1998 12:30:23.136364800 AM GMT
 |  | ||||||
| 
 |  | ||||||
| 	uuid := Parse("7d444840-9dc0-11d1-b245-5ffdce74fad2") |  | ||||||
| 	node := []byte{0x5f, 0xfd, 0xce, 0x74, 0xfa, 0xd2} |  | ||||||
| 
 |  | ||||||
| 	ts, ok := uuid.Time() |  | ||||||
| 	if ok { |  | ||||||
| 		c := time.Unix(ts.UnixTime()) |  | ||||||
| 		want := time.Date(1998, 2, 5, 0, 30, 23, 136364800, time.UTC) |  | ||||||
| 		if !c.Equal(want) { |  | ||||||
| 			t.Errorf("Got time %v, want %v", c, want) |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("%s: bad time\n", uuid) |  | ||||||
| 	} |  | ||||||
| 	if !bytes.Equal(node, uuid.NodeID()) { |  | ||||||
| 		t.Errorf("Expected node %v got %v\n", node, uuid.NodeID()) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestMD5(t *testing.T) { |  | ||||||
| 	uuid := NewMD5(NameSpace_DNS, []byte("python.org")).String() |  | ||||||
| 	want := "6fa459ea-ee8a-3ca4-894e-db77e160355e" |  | ||||||
| 	if uuid != want { |  | ||||||
| 		t.Errorf("MD5: got %q expected %q\n", uuid, want) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestSHA1(t *testing.T) { |  | ||||||
| 	uuid := NewSHA1(NameSpace_DNS, []byte("python.org")).String() |  | ||||||
| 	want := "886313e1-3b8a-5372-9b90-0c9aee199e5d" |  | ||||||
| 	if uuid != want { |  | ||||||
| 		t.Errorf("SHA1: got %q expected %q\n", uuid, want) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestNodeID(t *testing.T) { |  | ||||||
| 	nid := []byte{1, 2, 3, 4, 5, 6} |  | ||||||
| 	SetNodeInterface("") |  | ||||||
| 	s := NodeInterface() |  | ||||||
| 	if s == "" || s == "user" { |  | ||||||
| 		t.Errorf("NodeInterface %q after SetInteface\n", s) |  | ||||||
| 	} |  | ||||||
| 	node1 := NodeID() |  | ||||||
| 	if node1 == nil { |  | ||||||
| 		t.Errorf("NodeID nil after SetNodeInterface\n", s) |  | ||||||
| 	} |  | ||||||
| 	SetNodeID(nid) |  | ||||||
| 	s = NodeInterface() |  | ||||||
| 	if s != "user" { |  | ||||||
| 		t.Errorf("Expected NodeInterface %q got %q\n", "user", s) |  | ||||||
| 	} |  | ||||||
| 	node2 := NodeID() |  | ||||||
| 	if node2 == nil { |  | ||||||
| 		t.Errorf("NodeID nil after SetNodeID\n", s) |  | ||||||
| 	} |  | ||||||
| 	if bytes.Equal(node1, node2) { |  | ||||||
| 		t.Errorf("NodeID not changed after SetNodeID\n", s) |  | ||||||
| 	} else if !bytes.Equal(nid, node2) { |  | ||||||
| 		t.Errorf("NodeID is %x, expected %x\n", node2, nid) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func testDCE(t *testing.T, name string, uuid UUID, domain Domain, id uint32) { |  | ||||||
| 	if uuid == nil { |  | ||||||
| 		t.Errorf("%s failed\n", name) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if v, _ := uuid.Version(); v != 2 { |  | ||||||
| 		t.Errorf("%s: %s: expected version 2, got %s\n", name, uuid, v) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 	if v, ok := uuid.Domain(); !ok || v != domain { |  | ||||||
| 		if !ok { |  | ||||||
| 			t.Errorf("%s: %d: Domain failed\n", name, uuid) |  | ||||||
| 		} else { |  | ||||||
| 			t.Errorf("%s: %s: expected domain %d, got %d\n", name, uuid, domain, v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	if v, ok := uuid.Id(); !ok || v != id { |  | ||||||
| 		if !ok { |  | ||||||
| 			t.Errorf("%s: %d: Id failed\n", name, uuid) |  | ||||||
| 		} else { |  | ||||||
| 			t.Errorf("%s: %s: expected id %d, got %d\n", name, uuid, id, v) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestDCE(t *testing.T) { |  | ||||||
| 	testDCE(t, "NewDCESecurity", NewDCESecurity(42, 12345678), 42, 12345678) |  | ||||||
| 	testDCE(t, "NewDCEPerson", NewDCEPerson(), Person, uint32(os.Getuid())) |  | ||||||
| 	testDCE(t, "NewDCEGroup", NewDCEGroup(), Group, uint32(os.Getgid())) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type badRand struct{} |  | ||||||
| 
 |  | ||||||
| func (r badRand) Read(buf []byte) (int, error) { |  | ||||||
| 	for i, _ := range buf { |  | ||||||
| 		buf[i] = byte(i) |  | ||||||
| 	} |  | ||||||
| 	return len(buf), nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func TestBadRand(t *testing.T) { |  | ||||||
| 	SetRand(badRand{}) |  | ||||||
| 	uuid1 := New() |  | ||||||
| 	uuid2 := New() |  | ||||||
| 	if uuid1 != uuid2 { |  | ||||||
| 		t.Errorf("execpted duplicates, got %q and %q\n", uuid1, uuid2) |  | ||||||
| 	} |  | ||||||
| 	SetRand(nil) |  | ||||||
| 	uuid1 = New() |  | ||||||
| 	uuid2 = New() |  | ||||||
| 	if uuid1 == uuid2 { |  | ||||||
| 		t.Errorf("unexecpted duplicates, got %q\n", uuid1) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,41 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| import ( |  | ||||||
| 	"encoding/binary" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // NewUUID returns a Version 1 UUID based on the current NodeID and clock
 |  | ||||||
| // sequence, and the current time.  If the NodeID has not been set by SetNodeID
 |  | ||||||
| // or SetNodeInterface then it will be set automatically.  If the NodeID cannot
 |  | ||||||
| // be set NewUUID returns nil.  If clock sequence has not been set by
 |  | ||||||
| // SetClockSequence then it will be set automatically.  If GetTime fails to
 |  | ||||||
| // return the current NewUUID returns nil.
 |  | ||||||
| func NewUUID() UUID { |  | ||||||
| 	if nodeID == nil { |  | ||||||
| 		SetNodeInterface("") |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	now, seq, err := GetTime() |  | ||||||
| 	if err != nil { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	uuid := make([]byte, 16) |  | ||||||
| 
 |  | ||||||
| 	time_low := uint32(now & 0xffffffff) |  | ||||||
| 	time_mid := uint16((now >> 32) & 0xffff) |  | ||||||
| 	time_hi := uint16((now >> 48) & 0x0fff) |  | ||||||
| 	time_hi |= 0x1000 // Version 1
 |  | ||||||
| 
 |  | ||||||
| 	binary.BigEndian.PutUint32(uuid[0:], time_low) |  | ||||||
| 	binary.BigEndian.PutUint16(uuid[4:], time_mid) |  | ||||||
| 	binary.BigEndian.PutUint16(uuid[6:], time_hi) |  | ||||||
| 	binary.BigEndian.PutUint16(uuid[8:], seq) |  | ||||||
| 	copy(uuid[10:], nodeID) |  | ||||||
| 
 |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
|  | @ -1,25 +0,0 @@ | ||||||
| // Copyright 2011 Google Inc.  All rights reserved.
 |  | ||||||
| // Use of this source code is governed by a BSD-style
 |  | ||||||
| // license that can be found in the LICENSE file.
 |  | ||||||
| 
 |  | ||||||
| package uuid |  | ||||||
| 
 |  | ||||||
| // Random returns a Random (Version 4) UUID or panics.
 |  | ||||||
| //
 |  | ||||||
| // The strength of the UUIDs is based on the strength of the crypto/rand
 |  | ||||||
| // package.
 |  | ||||||
| //
 |  | ||||||
| // A note about uniqueness derived from from the UUID Wikipedia entry:
 |  | ||||||
| //
 |  | ||||||
| //  Randomly generated UUIDs have 122 random bits.  One's annual risk of being
 |  | ||||||
| //  hit by a meteorite is estimated to be one chance in 17 billion, that
 |  | ||||||
| //  means the probability is about 0.00000000006 (6 × 10−11),
 |  | ||||||
| //  equivalent to the odds of creating a few tens of trillions of UUIDs in a
 |  | ||||||
| //  year and having one duplicate.
 |  | ||||||
| func NewRandom() UUID { |  | ||||||
| 	uuid := make([]byte, 16) |  | ||||||
| 	randomBits([]byte(uuid)) |  | ||||||
| 	uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4
 |  | ||||||
| 	uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10
 |  | ||||||
| 	return uuid |  | ||||||
| } |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| package context | package context | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"code.google.com/p/go-uuid/uuid" | 	"github.com/docker/distribution/uuid" | ||||||
| 	"golang.org/x/net/context" | 	"golang.org/x/net/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -27,7 +27,7 @@ func (ic *instanceContext) Value(key interface{}) interface{} { | ||||||
| 
 | 
 | ||||||
| var background = &instanceContext{ | var background = &instanceContext{ | ||||||
| 	Context: context.Background(), | 	Context: context.Background(), | ||||||
| 	id:      uuid.New(), | 	id:      uuid.Generate().String(), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Background returns a non-nil, empty Context. The background context
 | // Background returns a non-nil, empty Context. The background context
 | ||||||
|  |  | ||||||
|  | @ -8,8 +8,8 @@ import ( | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	log "github.com/Sirupsen/logrus" | 	log "github.com/Sirupsen/logrus" | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
| 	"github.com/gorilla/mux" | 	"github.com/gorilla/mux" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -79,7 +79,7 @@ func WithRequest(ctx Context, r *http.Request) Context { | ||||||
| 	return &httpRequestContext{ | 	return &httpRequestContext{ | ||||||
| 		Context:   ctx, | 		Context:   ctx, | ||||||
| 		startedAt: time.Now(), | 		startedAt: time.Now(), | ||||||
| 		id:        uuid.New(), // assign the request a unique.
 | 		id:        uuid.Generate().String(), | ||||||
| 		r:         r, | 		r:         r, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,6 +3,8 @@ package context | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
|  | 
 | ||||||
| 	"github.com/Sirupsen/logrus" | 	"github.com/Sirupsen/logrus" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -99,3 +101,8 @@ func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry { | ||||||
| 
 | 
 | ||||||
| 	return logger.WithFields(fields) | 	return logger.WithFields(fields) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func init() { | ||||||
|  | 	// inject a logger into the uuid library.
 | ||||||
|  | 	uuid.Loggerf = GetLogger(Background()).Warnf | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import ( | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" | 	"github.com/docker/distribution/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // WithTrace allocates a traced timing span in a new context. This allows a
 | // WithTrace allocates a traced timing span in a new context. This allows a
 | ||||||
|  | @ -45,7 +45,7 @@ func WithTrace(ctx Context) (Context, func(format string, a ...interface{})) { | ||||||
| 	f := runtime.FuncForPC(pc) | 	f := runtime.FuncForPC(pc) | ||||||
| 	ctx = &traced{ | 	ctx = &traced{ | ||||||
| 		Context: ctx, | 		Context: ctx, | ||||||
| 		id:      uuid.New(), | 		id:      uuid.Generate().String(), | ||||||
| 		start:   time.Now(), | 		start:   time.Now(), | ||||||
| 		parent:  GetStringValue(ctx, "trace.id"), | 		parent:  GetStringValue(ctx, "trace.id"), | ||||||
| 		fnname:  f.Name(), | 		fnname:  f.Name(), | ||||||
|  |  | ||||||
|  | @ -4,11 +4,11 @@ import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	"github.com/docker/distribution" | 	"github.com/docker/distribution" | ||||||
| 	"github.com/docker/distribution/context" | 	"github.com/docker/distribution/context" | ||||||
| 	"github.com/docker/distribution/digest" | 	"github.com/docker/distribution/digest" | ||||||
| 	"github.com/docker/distribution/manifest" | 	"github.com/docker/distribution/manifest" | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type bridge struct { | type bridge struct { | ||||||
|  | @ -149,7 +149,7 @@ func (b *bridge) createEvent(action string) *Event { | ||||||
| // createEvent returns a new event, timestamped, with the specified action.
 | // createEvent returns a new event, timestamped, with the specified action.
 | ||||||
| func createEvent(action string) *Event { | func createEvent(action string) *Event { | ||||||
| 	return &Event{ | 	return &Event{ | ||||||
| 		ID:        uuid.New(), | 		ID:        uuid.Generate().String(), | ||||||
| 		Timestamp: time.Now(), | 		Timestamp: time.Now(), | ||||||
| 		Action:    action, | 		Action:    action, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" | 	"github.com/docker/distribution/uuid" | ||||||
| 
 | 
 | ||||||
| 	"github.com/docker/distribution" | 	"github.com/docker/distribution" | ||||||
| 	"github.com/docker/distribution/context" | 	"github.com/docker/distribution/context" | ||||||
|  | @ -141,7 +141,7 @@ func TestBlobUploadChunked(t *testing.T) { | ||||||
| 		b1[513:1024], | 		b1[513:1024], | ||||||
| 	} | 	} | ||||||
| 	repo := "test.example.com/uploadrepo" | 	repo := "test.example.com/uploadrepo" | ||||||
| 	uuids := []string{uuid.New()} | 	uuids := []string{uuid.Generate().String()} | ||||||
| 	m = append(m, testutil.RequestResponseMapping{ | 	m = append(m, testutil.RequestResponseMapping{ | ||||||
| 		Request: testutil.Request{ | 		Request: testutil.Request{ | ||||||
| 			Method: "POST", | 			Method: "POST", | ||||||
|  | @ -159,7 +159,7 @@ func TestBlobUploadChunked(t *testing.T) { | ||||||
| 	}) | 	}) | ||||||
| 	offset := 0 | 	offset := 0 | ||||||
| 	for i, chunk := range chunks { | 	for i, chunk := range chunks { | ||||||
| 		uuids = append(uuids, uuid.New()) | 		uuids = append(uuids, uuid.Generate().String()) | ||||||
| 		newOffset := offset + len(chunk) | 		newOffset := offset + len(chunk) | ||||||
| 		m = append(m, testutil.RequestResponseMapping{ | 		m = append(m, testutil.RequestResponseMapping{ | ||||||
| 			Request: testutil.Request{ | 			Request: testutil.Request{ | ||||||
|  | @ -256,7 +256,7 @@ func TestBlobUploadMonolithic(t *testing.T) { | ||||||
| 	dgst, b1 := newRandomBlob(1024) | 	dgst, b1 := newRandomBlob(1024) | ||||||
| 	var m testutil.RequestResponseMap | 	var m testutil.RequestResponseMap | ||||||
| 	repo := "test.example.com/uploadrepo" | 	repo := "test.example.com/uploadrepo" | ||||||
| 	uploadID := uuid.New() | 	uploadID := uuid.Generate().String() | ||||||
| 	m = append(m, testutil.RequestResponseMapping{ | 	m = append(m, testutil.RequestResponseMapping{ | ||||||
| 		Request: testutil.Request{ | 		Request: testutil.Request{ | ||||||
| 			Method: "POST", | 			Method: "POST", | ||||||
|  |  | ||||||
|  | @ -4,11 +4,11 @@ import ( | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	"github.com/docker/distribution" | 	"github.com/docker/distribution" | ||||||
| 	"github.com/docker/distribution/context" | 	"github.com/docker/distribution/context" | ||||||
| 	"github.com/docker/distribution/digest" | 	"github.com/docker/distribution/digest" | ||||||
| 	"github.com/docker/distribution/registry/storage/driver" | 	"github.com/docker/distribution/registry/storage/driver" | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // linkedBlobStore provides a full BlobService that namespaces the blobs to a
 | // linkedBlobStore provides a full BlobService that namespaces the blobs to a
 | ||||||
|  | @ -85,7 +85,7 @@ func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) | ||||||
| func (lbs *linkedBlobStore) Create(ctx context.Context) (distribution.BlobWriter, error) { | func (lbs *linkedBlobStore) Create(ctx context.Context) (distribution.BlobWriter, error) { | ||||||
| 	context.GetLogger(ctx).Debug("(*linkedBlobStore).Writer") | 	context.GetLogger(ctx).Debug("(*linkedBlobStore).Writer") | ||||||
| 
 | 
 | ||||||
| 	uuid := uuid.New() | 	uuid := uuid.Generate().String() | ||||||
| 	startedAt := time.Now().UTC() | 	startedAt := time.Now().UTC() | ||||||
| 
 | 
 | ||||||
| 	path, err := lbs.blobStore.pm.path(uploadDataPathSpec{ | 	path, err := lbs.blobStore.pm.path(uploadDataPathSpec{ | ||||||
|  |  | ||||||
|  | @ -5,10 +5,10 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	log "github.com/Sirupsen/logrus" | 	log "github.com/Sirupsen/logrus" | ||||||
| 	"github.com/docker/distribution/context" | 	"github.com/docker/distribution/context" | ||||||
| 	storageDriver "github.com/docker/distribution/registry/storage/driver" | 	storageDriver "github.com/docker/distribution/registry/storage/driver" | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // uploadData stored the location of temporary files created during a layer upload
 | // uploadData stored the location of temporary files created during a layer upload
 | ||||||
|  | @ -116,8 +116,8 @@ func getOutstandingUploads(ctx context.Context, driver storageDriver.StorageDriv | ||||||
| func uUIDFromPath(path string) (string, bool) { | func uUIDFromPath(path string) (string, bool) { | ||||||
| 	components := strings.Split(path, "/") | 	components := strings.Split(path, "/") | ||||||
| 	for i := len(components) - 1; i >= 0; i-- { | 	for i := len(components) - 1; i >= 0; i-- { | ||||||
| 		if uuid := uuid.Parse(components[i]); uuid != nil { | 		if u, err := uuid.Parse(components[i]); err == nil { | ||||||
| 			return uuid.String(), i == len(components)-1 | 			return u.String(), i == len(components)-1 | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return "", false | 	return "", false | ||||||
|  |  | ||||||
|  | @ -6,10 +6,10 @@ import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"code.google.com/p/go-uuid/uuid" |  | ||||||
| 	"github.com/docker/distribution/context" | 	"github.com/docker/distribution/context" | ||||||
| 	"github.com/docker/distribution/registry/storage/driver" | 	"github.com/docker/distribution/registry/storage/driver" | ||||||
| 	"github.com/docker/distribution/registry/storage/driver/inmemory" | 	"github.com/docker/distribution/registry/storage/driver/inmemory" | ||||||
|  | 	"github.com/docker/distribution/uuid" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var pm = defaultPathMapper | var pm = defaultPathMapper | ||||||
|  | @ -18,7 +18,7 @@ func testUploadFS(t *testing.T, numUploads int, repoName string, startedAt time. | ||||||
| 	d := inmemory.New() | 	d := inmemory.New() | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	for i := 0; i < numUploads; i++ { | 	for i := 0; i < numUploads; i++ { | ||||||
| 		addUploads(ctx, t, d, uuid.New(), repoName, startedAt) | 		addUploads(ctx, t, d, uuid.Generate().String(), repoName, startedAt) | ||||||
| 	} | 	} | ||||||
| 	return d, ctx | 	return d, ctx | ||||||
| } | } | ||||||
|  | @ -73,7 +73,7 @@ func TestPurgeAll(t *testing.T) { | ||||||
| 	fs, ctx := testUploadFS(t, uploadCount, "test-repo", oneHourAgo) | 	fs, ctx := testUploadFS(t, uploadCount, "test-repo", oneHourAgo) | ||||||
| 
 | 
 | ||||||
| 	// Ensure > 1 repos are purged
 | 	// Ensure > 1 repos are purged
 | ||||||
| 	addUploads(ctx, t, fs, uuid.New(), "test-repo2", oneHourAgo) | 	addUploads(ctx, t, fs, uuid.Generate().String(), "test-repo2", oneHourAgo) | ||||||
| 	uploadCount++ | 	uploadCount++ | ||||||
| 
 | 
 | ||||||
| 	deleted, errs := PurgeUploads(ctx, fs, time.Now(), true) | 	deleted, errs := PurgeUploads(ctx, fs, time.Now(), true) | ||||||
|  | @ -95,7 +95,7 @@ func TestPurgeSome(t *testing.T) { | ||||||
| 	newUploadCount := 4 | 	newUploadCount := 4 | ||||||
| 
 | 
 | ||||||
| 	for i := 0; i < newUploadCount; i++ { | 	for i := 0; i < newUploadCount; i++ { | ||||||
| 		addUploads(ctx, t, fs, uuid.New(), "test-repo", time.Now().Add(1*time.Hour)) | 		addUploads(ctx, t, fs, uuid.Generate().String(), "test-repo", time.Now().Add(1*time.Hour)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	deleted, errs := PurgeUploads(ctx, fs, time.Now(), true) | 	deleted, errs := PurgeUploads(ctx, fs, time.Now(), true) | ||||||
|  | @ -115,7 +115,7 @@ func TestPurgeOnlyUploads(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| 	// Create a directory tree outside _uploads and ensure
 | 	// Create a directory tree outside _uploads and ensure
 | ||||||
| 	// these files aren't deleted.
 | 	// these files aren't deleted.
 | ||||||
| 	dataPath, err := pm.path(uploadDataPathSpec{name: "test-repo", id: uuid.New()}) | 	dataPath, err := pm.path(uploadDataPathSpec{name: "test-repo", id: uuid.Generate().String()}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf(err.Error()) | 		t.Fatalf(err.Error()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -0,0 +1,112 @@ | ||||||
|  | // Package uuid provides simple UUID generation. Only version 4 style UUIDs
 | ||||||
|  | // can be generated.
 | ||||||
|  | //
 | ||||||
|  | // Please see http://tools.ietf.org/html/rfc4122 for details on UUIDs.
 | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"crypto/rand" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"log" | ||||||
|  | 	"syscall" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	// Bits is the number of bits in a UUID
 | ||||||
|  | 	Bits = 128 | ||||||
|  | 
 | ||||||
|  | 	// Size is the number of bytes in a UUID
 | ||||||
|  | 	Size = Bits / 8 | ||||||
|  | 
 | ||||||
|  | 	format = "%08x-%04x-%04x-%04x-%012x" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	// ErrUUIDInvalid indicates a parsed string is not a valid uuid.
 | ||||||
|  | 	ErrUUIDInvalid = fmt.Errorf("invalid uuid") | ||||||
|  | 
 | ||||||
|  | 	// Loggerf can be used to override the default logging destination. Such
 | ||||||
|  | 	// log messages in this library should be logged at warning or higher.
 | ||||||
|  | 	Loggerf = log.Printf | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // UUID represents a UUID value. UUIDs can be compared and set to other values
 | ||||||
|  | // and accessed by byte.
 | ||||||
|  | type UUID [Size]byte | ||||||
|  | 
 | ||||||
|  | // Generate creates a new, version 4 uuid.
 | ||||||
|  | func Generate() (u UUID) { | ||||||
|  | 	const ( | ||||||
|  | 		// ensures we backoff for less than 450ms total. Use the following to
 | ||||||
|  | 		// select new value, in units of 10ms:
 | ||||||
|  | 		// 	n*(n+1)/2 = d -> n^2 + n - 2d -> n = (sqrt(8d + 1) - 1)/2
 | ||||||
|  | 		maxretries = 9 | ||||||
|  | 		backoff    = time.Millisecond * 10 | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	var ( | ||||||
|  | 		totalBackoff time.Duration | ||||||
|  | 		retries      int | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
|  | 	for { | ||||||
|  | 		// This should never block but the read may fail. Because of this,
 | ||||||
|  | 		// we just try to read the random number generator until we get
 | ||||||
|  | 		// something. This is a very rare condition but may happen.
 | ||||||
|  | 		b := time.Duration(retries) * backoff | ||||||
|  | 		time.Sleep(b) | ||||||
|  | 		totalBackoff += b | ||||||
|  | 
 | ||||||
|  | 		_, err := io.ReadFull(rand.Reader, u[:]) | ||||||
|  | 		if err != nil { | ||||||
|  | 			if err == syscall.EPERM { | ||||||
|  | 				// EPERM represents an entropy pool exhaustion, a condition under
 | ||||||
|  | 				// which we backoff and retry.
 | ||||||
|  | 				if retries < maxretries { | ||||||
|  | 					retries++ | ||||||
|  | 					Loggerf("error generating version 4 uuid, retrying: %v", err) | ||||||
|  | 					continue | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Any other errors represent a system problem. What did someone
 | ||||||
|  | 			// do to /dev/urandom?
 | ||||||
|  | 			panic(fmt.Errorf("error reading random number generator, retried for %v: %v", totalBackoff, err)) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		break | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	u[6] = (u[6] & 0x0f) | 0x40 // set version byte
 | ||||||
|  | 	u[8] = (u[8] & 0x3f) | 0x80 // set high order byte 0b10{8,9,a,b}
 | ||||||
|  | 
 | ||||||
|  | 	return u | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Parse attempts to extract a uuid from the string or returns an error.
 | ||||||
|  | func Parse(s string) (u UUID, err error) { | ||||||
|  | 	if len(s) != 36 { | ||||||
|  | 		return UUID{}, ErrUUIDInvalid | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// create stack addresses for each section of the uuid.
 | ||||||
|  | 	p := make([][]byte, 5) | ||||||
|  | 
 | ||||||
|  | 	if _, err := fmt.Sscanf(s, format, &p[0], &p[1], &p[2], &p[3], &p[4]); err != nil { | ||||||
|  | 		return u, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	copy(u[0:4], p[0]) | ||||||
|  | 	copy(u[4:6], p[1]) | ||||||
|  | 	copy(u[6:8], p[2]) | ||||||
|  | 	copy(u[8:10], p[3]) | ||||||
|  | 	copy(u[10:16], p[4]) | ||||||
|  | 
 | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (u UUID) String() string { | ||||||
|  | 	return fmt.Sprintf(format, u[:4], u[4:6], u[6:8], u[8:10], u[10:]) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,48 @@ | ||||||
|  | package uuid | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const iterations = 1000 | ||||||
|  | 
 | ||||||
|  | func TestUUID4Generation(t *testing.T) { | ||||||
|  | 	for i := 0; i < iterations; i++ { | ||||||
|  | 		u := Generate() | ||||||
|  | 
 | ||||||
|  | 		if u[6]&0xf0 != 0x40 { | ||||||
|  | 			t.Fatalf("version byte not correctly set: %v, %08b %08b", u, u[6], u[6]&0xf0) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if u[8]&0xc0 != 0x80 { | ||||||
|  | 			t.Fatalf("top order 8th byte not correctly set: %v, %b", u, u[8]) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestParseAndEquality(t *testing.T) { | ||||||
|  | 	for i := 0; i < iterations; i++ { | ||||||
|  | 		u := Generate() | ||||||
|  | 
 | ||||||
|  | 		parsed, err := Parse(u.String()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Fatalf("error parsing uuid %v: %v", u, err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if parsed != u { | ||||||
|  | 			t.Fatalf("parsing round trip failed: %v != %v", parsed, u) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, c := range []string{ | ||||||
|  | 		"bad", | ||||||
|  | 		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",    // correct length, incorrect format
 | ||||||
|  | 		"  20cc7775-2671-43c7-8742-51d1cfa23258",  // leading space
 | ||||||
|  | 		"20cc7775-2671-43c7-8742-51d1cfa23258   ", // trailing space
 | ||||||
|  | 		"00000000-0000-0000-0000-x00000000000   ", // out of range character
 | ||||||
|  | 	} { | ||||||
|  | 		if _, err := Parse(c); err == nil { | ||||||
|  | 			t.Fatalf("parsing %q should have failed", c) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue