diff --git a/doc/development.md b/doc/development.md index 3486008aa..b10c41d87 100644 --- a/doc/development.md +++ b/doc/development.md @@ -72,7 +72,6 @@ The following packages are required by the Blackbox Test: * `e2fsprogs` * `btrfs-progs` * `xfsprogs` -* `uuid-runtime` * `gdisk` * `coreutils` * `mdadm` @@ -97,6 +96,8 @@ Config: `string` The test should be added to the init function inside of the test file. If the test module is being created then an `init` function should be created which registers the tests and the package must be imported inside of `tests/registry/registry.go` to allow for discovery. +UUIDs may be required in the following fields of a Test object: In, Out, and Config. Replace all GUIDs with GUID varaibles which take on the format `$uuid` (e.g. $uuid123). Where `` must be a positive integer. GUID variables with identical `` fields will be replaced with identical GUIDs. For example, look at [tests/positive/partitions/zeros.go](https://github.com/coreos/ignition/blob/master/tests/positive/partitions/zeros.go). + ## Marking an experimental spec as stable When an experimental version of the Ignition config spec (e.g.: `2.3.0-experimental`) is to be declared stable (e.g. `2.3.0`), there are a handful of changes that must be made to the code base. These changes should have the following effects: diff --git a/glide.lock b/glide.lock index 693a63980..a4076ea98 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 73775bf0b3adebbea41e1027e485793028562d1d3461d87b69e8c874bce735df -updated: 2018-05-25T12:22:29.123848173-07:00 +hash: 1de154fd59f1a5e02d4a9a15815f7328fb7cb8ef232ded755432f2d3b1120419 +updated: 2018-06-14T16:10:53.870195521-07:00 imports: - name: github.com/ajeddeloh/go-json version: 73d058cf8437a1989030afe571eeab9f90eebbbd @@ -56,7 +56,6 @@ imports: - netascii - name: github.com/sigma/bdoor version: babf2a4017b020d4ce04e8167076186e82645dd1 - repo: https://github.com/sigma/bdoor - name: github.com/sigma/vmw-guestinfo version: 95dd4126d6e8b4ef1970b3f3fe2e8cdd470d2903 subpackages: @@ -85,6 +84,10 @@ testImports: version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 subpackages: - spew +- name: github.com/pborman/uuid + version: e790cca94e6cc75c7064b1332e63811d4aae1a53 + subpackages: + - assert - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: diff --git a/glide.yaml b/glide.yaml index 0ab43acd9..ba1f4a49c 100644 --- a/glide.yaml +++ b/glide.yaml @@ -39,5 +39,7 @@ import: testImport: - package: github.com/stretchr/testify version: 4d4bfba8f1d1027c4fdbe371823030df51419987 +- package: github.com/pborman/uuid + version: v1.1 subpackages: - assert diff --git a/tests/blackbox_test.go b/tests/blackbox_test.go index c99b0d8ea..3f5660df1 100644 --- a/tests/blackbox_test.go +++ b/tests/blackbox_test.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "os" "path/filepath" + "regexp" "strings" "testing" "time" @@ -30,6 +31,9 @@ import ( // Register the tests _ "github.com/coreos/ignition/tests/registry" + + // UUID generation tool + "github.com/pborman/uuid" ) var ( @@ -76,6 +80,9 @@ func TestIgnitionBlackBoxNegative(t *testing.T) { func outer(t *testing.T, test types.Test, negativeTests bool) error { t.Log(test.Name) + // Maps $uuid such that two variables with the same have identical UUID + UUIDmap := make(map[string]string) + ctx, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(testTimeout)) defer cancelFunc() @@ -123,7 +130,7 @@ func outer(t *testing.T, test types.Test, negativeTests bool) error { // Finish data setup for _, part := range disk.Partitions { if part.GUID == "" { - part.GUID, err = generateUUID(t, ctx) + part.GUID = uuid.New() if err != nil { return err } @@ -143,6 +150,46 @@ func outer(t *testing.T, test types.Test, negativeTests bool) error { } test.Out[i].SetOffsets() + // Replace all UUID variables (format $uuid) in configs and partitions with an UUID + test.Config, err = replaceUUIDVars(t, test.Config, UUIDmap) + if err != nil { + return err + } + + for _, disk := range test.In { + for _, partition := range disk.Partitions { + partition.TypeGUID, err = replaceUUIDVars(t, partition.TypeGUID, UUIDmap) + if err != nil { + return err + } + partition.GUID, err = replaceUUIDVars(t, partition.GUID, UUIDmap) + if err != nil { + return err + } + partition.FilesystemUUID, err = replaceUUIDVars(t, partition.FilesystemUUID, UUIDmap) + if err != nil { + return err + } + } + } + + for _, disk := range test.Out { + for _, partition := range disk.Partitions { + partition.TypeGUID, err = replaceUUIDVars(t, partition.TypeGUID, UUIDmap) + if err != nil { + return err + } + partition.GUID, err = replaceUUIDVars(t, partition.GUID, UUIDmap) + if err != nil { + return err + } + partition.FilesystemUUID, err = replaceUUIDVars(t, partition.FilesystemUUID, UUIDmap) + if err != nil { + return err + } + } + } + // Creation err = createVolume(t, ctx, tmpDirectory, i, disk.ImageFile, imageSize, disk.Partitions) // Move value into the local scope, because disk.ImageFile will change @@ -311,3 +358,28 @@ func outer(t *testing.T, test types.Test, negativeTests bool) error { } return nil } + +// Identify and replace $uuid with correct UUID +// Variables with matching should have identical UUIDs +func replaceUUIDVars(t *testing.T, str string, UUIDmap map[string]string) (string, error) { + finalStr := str + + pattern := regexp.MustCompile("\\$uuid([0-9]+)") + for _, match := range pattern.FindAllStringSubmatch(str, -1) { + if len(match) != 2 { + return str, fmt.Errorf("find all string submatch error: want length of 2, got length of %d", len(match)) + } + + finalStr = strings.Replace(finalStr, match[0], getUUID(match[0], UUIDmap), 1) + } + return finalStr, nil +} + +// Format: $uuid where the uuid variable (uuid) is the key +// value is the UUID for this uuid variable +func getUUID(key string, UUIDmap map[string]string) string { + if _, ok := UUIDmap[key]; !ok { + UUIDmap[key] = uuid.New() + } + return UUIDmap[key] +} diff --git a/tests/filesystem.go b/tests/filesystem.go index 7f9249ea8..1ce71052b 100644 --- a/tests/filesystem.go +++ b/tests/filesystem.go @@ -376,14 +376,6 @@ func removeEmpty(strings []string) []string { return r } -func generateUUID(t *testing.T, ctx context.Context) (string, error) { - out, err := run(t, ctx, "uuidgen") - if err != nil { - return "", err - } - return strings.TrimSpace(string(out)), nil -} - func createFilesForPartitions(t *testing.T, partitions []*types.Partition) error { for _, partition := range partitions { err := createDirectoriesFromSlice(t, partition.MountPath, partition.Directories) diff --git a/tests/positive/filesystems/reformat_filesystem.go b/tests/positive/filesystems/reformat_filesystem.go index a6db76c2a..736d6b1ce 100644 --- a/tests/positive/filesystems/reformat_filesystem.go +++ b/tests/positive/filesystems/reformat_filesystem.go @@ -49,7 +49,7 @@ func ReformatToBTRFS_2_0_0() types.Test { "format": "btrfs", "create": { "force": true, - "options": [ "--label=OEM", "--uuid=CA7D7CCB-63ED-4C53-861C-1742536059D4" ] + "options": [ "--label=OEM", "--uuid=$uuid0" ] } } }] @@ -85,7 +85,7 @@ func ReformatToXFS_2_0_0() types.Test { "format": "xfs", "create": { "force": true, - "options": [ "-L", "OEM", "-m", "uuid=CA7D7CCB-63ED-4C53-861C-1742536059CD" ] + "options": [ "-L", "OEM", "-m", "uuid=$uuid0" ] } } }] @@ -121,14 +121,14 @@ func ReformatToVFAT_2_0_0() types.Test { "format": "vfat", "create": { "force": true, - "options": [ "-n", "OEM", "-i", "CA7D7CCB-63ED-4C53-861C-1742536059CE" ] + "options": [ "-n", "OEM", "-i", "$uuid0" ] } } }] } }` out[0].Partitions.GetPartition("OEM").FilesystemType = "vfat" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059CE" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, @@ -158,7 +158,7 @@ func ReformatToEXT4_2_0_0() types.Test { "format": "ext4", "create": { "force": true, - "options": [ "-L", "OEM", "-U", "CA7D7CCB-63ED-4C53-861C-1742536059CF" ] + "options": [ "-L", "OEM", "-U", "$uuid0" ] } } }] @@ -166,7 +166,7 @@ func ReformatToEXT4_2_0_0() types.Test { }` in[0].Partitions.GetPartition("OEM").FilesystemType = "ext2" out[0].Partitions.GetPartition("OEM").FilesystemType = "ext4" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059CF" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, @@ -195,14 +195,14 @@ func ReformatToBTRFS_2_1_0() types.Test { "device": "$DEVICE", "format": "btrfs", "label": "OEM", - "uuid": "CA7D7CCB-63ED-4C53-861C-1742536059D0", + "uuid": "$uuid0", "wipeFilesystem": true } }] } }` out[0].Partitions.GetPartition("OEM").FilesystemType = "btrfs" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059D0" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, @@ -231,14 +231,14 @@ func ReformatToXFS_2_1_0() types.Test { "device": "$DEVICE", "format": "xfs", "label": "OEM", - "uuid": "CA7D7CCB-63ED-4C53-861C-1742536059D1", + "uuid": "$uuid0", "wipeFilesystem": true } }] } }` out[0].Partitions.GetPartition("OEM").FilesystemType = "xfs" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059D1" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, @@ -303,7 +303,7 @@ func ReformatToEXT4_2_1_0() types.Test { "device": "$DEVICE", "format": "ext4", "label": "OEM", - "uuid": "CA7D7CCB-63ED-4C53-861C-1742536059D2", + "uuid": "$uuid0", "wipeFilesystem": true } }] @@ -311,7 +311,7 @@ func ReformatToEXT4_2_1_0() types.Test { }` in[0].Partitions.GetPartition("OEM").FilesystemType = "ext2" out[0].Partitions.GetPartition("OEM").FilesystemType = "ext4" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059D2" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, @@ -340,7 +340,7 @@ func ReformatToSWAP_2_1_0() types.Test { "device": "$DEVICE", "format": "swap", "label": "OEM", - "uuid": "CA7D7CCB-63ED-4C53-861C-1742536059D3", + "uuid": "$uuid0", "wipeFilesystem": true } }] @@ -348,7 +348,7 @@ func ReformatToSWAP_2_1_0() types.Test { }` in[0].Partitions.GetPartition("OEM").FilesystemType = "ext2" out[0].Partitions.GetPartition("OEM").FilesystemType = "swap" - out[0].Partitions.GetPartition("OEM").FilesystemUUID = "CA7D7CCB-63ED-4C53-861C-1742536059D3" + out[0].Partitions.GetPartition("OEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, diff --git a/tests/positive/filesystems/reuse_filesystem.go b/tests/positive/filesystems/reuse_filesystem.go index 7c747ee26..3f714c1bd 100644 --- a/tests/positive/filesystems/reuse_filesystem.go +++ b/tests/positive/filesystems/reuse_filesystem.go @@ -43,7 +43,7 @@ func ReuseExistingFilesystem() types.Test { "wipeFilesystem": false, "format": "xfs", "label": "data", - "uuid": "8A7A6E26-5E8F-4CCA-A654-46215D4696AC" + "uuid": "$uuid0" } } ] @@ -58,7 +58,7 @@ func ReuseExistingFilesystem() types.Test { Length: 2621440, FilesystemType: "xfs", FilesystemLabel: "data", - FilesystemUUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + FilesystemUUID: "$uuid0", Files: []types.File{ { Node: types.Node{ @@ -80,7 +80,7 @@ func ReuseExistingFilesystem() types.Test { Length: 2621440, FilesystemType: "xfs", FilesystemLabel: "data", - FilesystemUUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + FilesystemUUID: "$uuid0", Files: []types.File{ { Node: types.Node{ diff --git a/tests/positive/partitions/complex.go b/tests/positive/partitions/complex.go index c28415b24..28281fa83 100644 --- a/tests/positive/partitions/complex.go +++ b/tests/positive/partitions/complex.go @@ -43,8 +43,8 @@ func KitchenSink() types.Test { "number": 1, "start": 2048, "size": 65536, - "typeGuid": "316f19f9-9e0f-431e-859e-ae6908dbe8ca", - "guid": "53f2e871-f468-437c-b90d-f3c6409df81a", + "typeGuid": "$uuid0", + "guid": "$uuid1", "wipePartitionEntry": true }, { @@ -57,8 +57,8 @@ func KitchenSink() types.Test { "number": 3, "size": 0, "start": 0, - "typeGuid": "6050e8fc-1e31-473b-bcc0-714e32fcb09d", - "guid": "f14984bc-6f08-4885-b668-526263469a00", + "typeGuid": "$uuid2", + "guid": "$uuid3", "wipePartitionEntry": true }, { @@ -82,22 +82,22 @@ func KitchenSink() types.Test { Label: "p1", Number: 1, Length: 131072, - TypeGUID: "316f19f9-9e0f-431e-859e-ae6908dbe8ca", - GUID: "3ED3993F-0016-422B-B134-09FCBA6F66EF", + TypeGUID: "$uuid0", + GUID: "$uuid4", }, { Label: "dont-delete", Number: 2, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "26cc1e6a-39a2-4502-a957-28f8e0ac00e7", + TypeGUID: "$uuid5", + GUID: "$uuid6", }, { Label: "garbo-town", Number: 3, Length: 65536, - TypeGUID: "9dfde6db-a308-497b-9f8c-55db12d4d9a1", - GUID: "115ee54b-00bd-4afe-be9b-bf1912dec92d", + TypeGUID: "$uuid7", + GUID: "$uuid8", }, { TypeCode: "blank", @@ -107,15 +107,15 @@ func KitchenSink() types.Test { Label: "more-junk", Number: 4, Length: 65536, - TypeGUID: "ee378f79-6b7a-4f7a-8029-7a5736d12bbf", - GUID: "5e89fa40-183c-4346-b2e1-2f10fa2190e1", + TypeGUID: "$uuid9", + GUID: "$uuid10", }, { Label: "dont-delete2", Number: 5, Length: 65536, - TypeGUID: "9dd1a91a-a39a-4594-b431-60a7fb630bcb", - GUID: "39baf7ef-cb3e-4343-8bfc-c2391b8b5607", + TypeGUID: "$uuid11", + GUID: "$uuid12", }, { TypeCode: "blank", @@ -130,29 +130,29 @@ func KitchenSink() types.Test { Label: "p1", Number: 1, Length: 65536, - TypeGUID: "316f19f9-9e0f-431e-859e-ae6908dbe8ca", - GUID: "53f2e871-f468-437c-b90d-f3c6409df81a", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Label: "dont-delete", Number: 2, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "26cc1e6a-39a2-4502-a957-28f8e0ac00e7", + TypeGUID: "$uuid5", + GUID: "$uuid6", }, { Label: "new-biggest", Number: 3, Length: 262144, - TypeGUID: "6050e8fc-1e31-473b-bcc0-714e32fcb09d", - GUID: "f14984bc-6f08-4885-b668-526263469a00", + TypeGUID: "$uuid2", + GUID: "$uuid3", }, { Label: "dont-delete2", Number: 5, Length: 65536, - TypeGUID: "9dd1a91a-a39a-4594-b431-60a7fb630bcb", - GUID: "39baf7ef-cb3e-4343-8bfc-c2391b8b5607", + TypeGUID: "$uuid11", + GUID: "$uuid12", }, { TypeCode: "blank", diff --git a/tests/positive/partitions/creation.go b/tests/positive/partitions/creation.go index fd8af03e9..791ccd44a 100644 --- a/tests/positive/partitions/creation.go +++ b/tests/positive/partitions/creation.go @@ -37,8 +37,8 @@ func CreatePartition() types.Test { Label: "create-partition", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "05AE8178-224E-4744-862A-4F4B042662D0", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, }, }) @@ -55,8 +55,8 @@ func CreatePartition() types.Test { "number": 1, "size": 65536, "label": "create-partition", - "typeGuid": "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - "guid": "05AE8178-224E-4744-862A-4F4B042662D0" + "typeGuid": "$uuid0", + "guid": "$uuid1" } ] } @@ -89,15 +89,15 @@ func WipeAndCreateNewPartitions() types.Test { "label": "important-data", "number": 1, "size": 65536, - "typeGuid": "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - "guid": "8A7A6E26-5E8F-4CCA-A654-46215D4696AC" + "typeGuid": "$uuid0", + "guid": "$uuid1" }, { "label": "ephemeral-data", "number": 2, "size": 131072, - "typeGuid": "CA7D7CCB-63ED-4C53-861C-1742536059CC", - "guid": "A51034E6-26B3-48DF-BEED-220562AC7AD1" + "typeGuid": "$uuid2", + "guid": "$uuid3" } ] } @@ -114,15 +114,15 @@ func WipeAndCreateNewPartitions() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid0", + GUID: "$uuid0", }, { Label: "ephemeral-data", Number: 2, Length: 131072, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid2", + GUID: "$uuid0", }, }, }) @@ -133,15 +133,15 @@ func WipeAndCreateNewPartitions() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Label: "ephemeral-data", Number: 2, Length: 131072, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "A51034E6-26B3-48DF-BEED-220562AC7AD1", + TypeGUID: "$uuid2", + GUID: "$uuid3", }, }, }) @@ -170,15 +170,15 @@ func AppendPartitions() types.Test { "label": "additional-partition", "number": 3, "size": 65536, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "3ED3993F-0016-422B-B134-09FCBA6F66EF" + "typeGuid": "$uuid0", + "guid": "$uuid1" }, { "label": "additional-partition2", "number": 4, "size": 65536, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "accedd09-76c2-4363-9893-f5689a78c47f" + "typeGuid": "$uuid0", + "guid": "$uuid2" }] }] } @@ -191,15 +191,15 @@ func AppendPartitions() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + TypeGUID: "$uuid3", + GUID: "$uuid4", }, { Label: "ephemeral-data", Number: 2, Length: 131072, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid5", + GUID: "$uuid3", }, }, }) @@ -210,29 +210,29 @@ func AppendPartitions() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + TypeGUID: "$uuid3", + GUID: "$uuid4", }, { Label: "ephemeral-data", Number: 2, Length: 131072, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid5", + GUID: "$uuid3", }, { Label: "additional-partition", Number: 3, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "3ED3993F-0016-422B-B134-09FCBA6F66EF", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Label: "additional-partition2", Number: 4, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "accedd09-76c2-4363-9893-f5689a78c47f", + TypeGUID: "$uuid0", + GUID: "$uuid2", }, }, }) @@ -262,7 +262,7 @@ func ResizeRoot() types.Test { "number": 9, "size": 13008896, "typeGuid": "3884DD41-8582-4404-B9A8-E9B84F2DF50E", - "guid": "3ED3993F-0016-422B-B134-09FCBA6F66EF", + "guid": "$uuid0", "wipePartitionEntry": true } ] diff --git a/tests/positive/partitions/mixed.go b/tests/positive/partitions/mixed.go index 466e95e8f..0753e6b4f 100644 --- a/tests/positive/partitions/mixed.go +++ b/tests/positive/partitions/mixed.go @@ -35,22 +35,22 @@ func Match1Recreate1Delete1Create1() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", - GUID: "8A7A6E26-5E8F-4CCA-A654-46215D4696AC", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Label: "ephemeral-data", Number: 2, Length: 65536, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid2", + GUID: "$uuid0", }, { Label: "bunch-of-junk", Number: 3, Length: 131072, - TypeGUID: "CA7D7CCB-63ED-4C53-861C-1742536059CC", - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid2", + GUID: "$uuid0", }, }, }) @@ -132,13 +132,13 @@ func NothingMatches() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid0", }, { Label: "ephemeral-data", Number: 2, Length: 65536, - GUID: "B921B045-1DF0-41C3-AF44-4C6F280D3FAE", + GUID: "$uuid0", }, { Label: "bunch-of-junk", @@ -154,13 +154,13 @@ func NothingMatches() types.Test { Label: "important-data", Number: 1, Length: 65536, - TypeGUID: "0921B045-1DF0-41C3-AF44-4C6F280D3FAE", + TypeGUID: "$uuid1", }, { Label: "ephemeral-data", Number: 2, Length: 65536, - GUID: "0921B045-1DF0-41C3-AF44-4C6F280D3FAE", + GUID: "$uuid1", }, { Label: "even-more-data", @@ -184,7 +184,7 @@ func NothingMatches() types.Test { "start": 2048, "size": 65536, "wipePartitionEntry": true, - "typeGuid": "0921B045-1DF0-41C3-AF44-4C6F280D3FAE" + "typeGuid": "$uuid1" }, { "label": "ephemeral-data", @@ -192,7 +192,7 @@ func NothingMatches() types.Test { "start": 67584, "size": 65536, "wipePartitionEntry": true, - "guid": "0921B045-1DF0-41C3-AF44-4C6F280D3FAE" + "guid": "$uuid1" }, { "label": "even-more-data", diff --git a/tests/positive/partitions/verification.go b/tests/positive/partitions/verification.go index 31826a1fe..dec125bba 100644 --- a/tests/positive/partitions/verification.go +++ b/tests/positive/partitions/verification.go @@ -56,7 +56,7 @@ func VerifyBaseDisk() types.Test { "number": 3, "start": 270336, "size": 2097152, - "typeGuid": "5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6", + "typeGuid": "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6", "guid": "7130c94a-213a-4e5a-8e26-6cce9662f132" }, { @@ -64,7 +64,7 @@ func VerifyBaseDisk() types.Test { "number": 4, "start": 2367488, "size": 2097152, - "typeGuid": "5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6", + "typeGuid": "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6", "guid": "e03dd35c-7c2d-4a47-b3fe-27f15780a57c" }, { @@ -86,7 +86,7 @@ func VerifyBaseDisk() types.Test { "number": 9, "start": 4857856, "size": 12943360, - "typeGuid": "3884dd41-8582-4404-b9a8-e9b84f2df50e" + "typeGuid": "3884DD41-8582-4404-B9A8-E9B84F2DF50E" } ] }] @@ -137,7 +137,7 @@ func VerifyBaseDiskWithWipe() types.Test { "start": 270336, "size": 2097152, "wipePartitionEntry": true, - "typeGuid": "5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6" + "typeGuid": "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6" }, { "label": "USR-B", @@ -145,7 +145,7 @@ func VerifyBaseDiskWithWipe() types.Test { "start": 2367488, "size": 2097152, "wipePartitionEntry": true, - "typeGuid": "5dfbf5f4-2848-4bac-aa5e-0d9a20b745a6", + "typeGuid": "5DFBF5F4-2848-4BAC-AA5E-0D9A20B745A6", "guid": "e03dd35c-7c2d-4a47-b3fe-27f15780a57c" }, { @@ -170,7 +170,7 @@ func VerifyBaseDiskWithWipe() types.Test { "start": 4857856, "size": 12943360, "wipePartitionEntry": true, - "typeGuid": "3884dd41-8582-4404-b9a8-e9b84f2df50e" + "typeGuid": "3884DD41-8582-4404-B9A8-E9B84F2DF50E" } ] }] diff --git a/tests/positive/partitions/zeros.go b/tests/positive/partitions/zeros.go index 8303067d3..bf53acb70 100644 --- a/tests/positive/partitions/zeros.go +++ b/tests/positive/partitions/zeros.go @@ -46,8 +46,8 @@ func PartitionSizeStart0() types.Test { "number": 1, "start": 0, "size": 0, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "3ED3993F-0016-422B-B134-09FCBA6F66EF" + "typeGuid": "$uuid0", + "guid": "$uuid1" }] }] } @@ -63,8 +63,8 @@ func PartitionSizeStart0() types.Test { Label: "fills-disk", Number: 1, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "3ED3993F-0016-422B-B134-09FCBA6F66EF", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, }, }) @@ -92,20 +92,20 @@ func PartitionStartNumber0() types.Test { "partitions": [{ "label": "uno", "size": 65536, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "3ED3993F-0016-422B-B134-09FCBA6F66EF" + "typeGuid": "$uuid0", + "guid": "$uuid1" }, { "label": "dos", "size": 65536, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "6A6BD6B9-4345-4AFB-974E-08D5A343E8F8" + "typeGuid": "$uuid0", + "guid": "$uuid2" }, { "label": "tres", "size": 65536, - "typeGuid": "F39C522B-9966-4429-A8F8-417CD5D83E5E", - "guid": "FE6108DC-096A-4E62-83CB-A11CE9D8E633" + "typeGuid": "$uuid0", + "guid": "$uuid3" }] }] } @@ -121,22 +121,22 @@ func PartitionStartNumber0() types.Test { Label: "uno", Number: 1, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "3ED3993F-0016-422B-B134-09FCBA6F66EF", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Label: "dos", Number: 2, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "6A6BD6B9-4345-4AFB-974E-08D5A343E8F8", + TypeGUID: "$uuid0", + GUID: "$uuid2", }, { Label: "tres", Number: 3, Length: 65536, - TypeGUID: "F39C522B-9966-4429-A8F8-417CD5D83E5E", - GUID: "FE6108DC-096A-4E62-83CB-A11CE9D8E633", + TypeGUID: "$uuid0", + GUID: "$uuid3", }, }, }) @@ -255,8 +255,8 @@ func NumberZeroHappensLast() types.Test { Number: 1, Label: "foobar", Length: 65536, - TypeGUID: "1f4ce97c-10fc-4daf-8b2c-0075bd34df43", - GUID: "8426957e-e444-40c8-93ed-f6c0d69cccde", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, }, }) @@ -267,8 +267,8 @@ func NumberZeroHappensLast() types.Test { Number: 1, Label: "foobar", Length: 65536, - TypeGUID: "1f4ce97c-10fc-4daf-8b2c-0075bd34df43", - GUID: "8426957e-e444-40c8-93ed-f6c0d69cccde", + TypeGUID: "$uuid0", + GUID: "$uuid1", }, { Number: 2, diff --git a/tests/positive/regression/filesystem.go b/tests/positive/regression/filesystem.go index 6d8a2251c..6dbf0ca15 100644 --- a/tests/positive/regression/filesystem.go +++ b/tests/positive/regression/filesystem.go @@ -43,7 +43,7 @@ func EquivalentFilesystemUUIDsTreatedDistinctEXT4() types.Test { "mount": { "device": "$DEVICE", "format": "ext4", - "uuid": "6ABE925E-6DAF-4FAD-BC09-8D56BE8822DE" + "uuid": "$uuid0" } } ] @@ -51,8 +51,8 @@ func EquivalentFilesystemUUIDsTreatedDistinctEXT4() types.Test { }` in[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemType = "ext4" out[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemType = "ext4" - in[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemUUID = "6ABE925E-6DAF-4FAD-BC09-8D56BE8822DE" - out[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemUUID = "6ABE925E-6DAF-4FAD-BC09-8D56BE8822DE" + in[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemUUID = "$uuid0" + out[0].Partitions.GetPartition("EFI-SYSTEM").FilesystemUUID = "$uuid0" return types.Test{ Name: name, diff --git a/vendor/github.com/pborman/uuid/LICENSE b/vendor/github.com/pborman/uuid/LICENSE new file mode 100644 index 000000000..5dc68268d --- /dev/null +++ b/vendor/github.com/pborman/uuid/LICENSE @@ -0,0 +1,27 @@ +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. diff --git a/vendor/github.com/pborman/uuid/dce.go b/vendor/github.com/pborman/uuid/dce.go new file mode 100644 index 000000000..50a0f2d09 --- /dev/null +++ b/vendor/github.com/pborman/uuid/dce.go @@ -0,0 +1,84 @@ +// 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)) +} diff --git a/vendor/github.com/pborman/uuid/doc.go b/vendor/github.com/pborman/uuid/doc.go new file mode 100644 index 000000000..d8bd013e6 --- /dev/null +++ b/vendor/github.com/pborman/uuid/doc.go @@ -0,0 +1,8 @@ +// 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 diff --git a/vendor/github.com/pborman/uuid/hash.go b/vendor/github.com/pborman/uuid/hash.go new file mode 100644 index 000000000..a0420c1ef --- /dev/null +++ b/vendor/github.com/pborman/uuid/hash.go @@ -0,0 +1,53 @@ +// 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 derived 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) +} diff --git a/vendor/github.com/pborman/uuid/marshal.go b/vendor/github.com/pborman/uuid/marshal.go new file mode 100644 index 000000000..6621dd54b --- /dev/null +++ b/vendor/github.com/pborman/uuid/marshal.go @@ -0,0 +1,83 @@ +// Copyright 2016 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" + "fmt" +) + +// MarshalText implements encoding.TextMarshaler. +func (u UUID) MarshalText() ([]byte, error) { + if len(u) != 16 { + return nil, nil + } + var js [36]byte + encodeHex(js[:], u) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (u *UUID) UnmarshalText(data []byte) error { + if len(data) == 0 { + return nil + } + id := Parse(string(data)) + if id == nil { + return errors.New("invalid UUID") + } + *u = id + return nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (u UUID) MarshalBinary() ([]byte, error) { + return u[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (u *UUID) UnmarshalBinary(data []byte) error { + if len(data) == 0 { + return nil + } + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + var id [16]byte + copy(id[:], data) + *u = id[:] + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (u Array) MarshalText() ([]byte, error) { + var js [36]byte + encodeHex(js[:], u[:]) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (u *Array) UnmarshalText(data []byte) error { + id := Parse(string(data)) + if id == nil { + return errors.New("invalid UUID") + } + *u = id.Array() + return nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (u Array) MarshalBinary() ([]byte, error) { + return u[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (u *Array) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(u[:], data) + return nil +} diff --git a/vendor/github.com/pborman/uuid/node.go b/vendor/github.com/pborman/uuid/node.go new file mode 100644 index 000000000..42d60da8f --- /dev/null +++ b/vendor/github.com/pborman/uuid/node.go @@ -0,0 +1,117 @@ +// 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" + "sync" +) + +var ( + nodeMu sync.Mutex + 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 { + defer nodeMu.Unlock() + nodeMu.Lock() + 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 { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +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 { + defer nodeMu.Unlock() + nodeMu.Lock() + 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 { + defer nodeMu.Unlock() + nodeMu.Lock() + 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 +} diff --git a/vendor/github.com/pborman/uuid/sql.go b/vendor/github.com/pborman/uuid/sql.go new file mode 100644 index 000000000..d015bfd13 --- /dev/null +++ b/vendor/github.com/pborman/uuid/sql.go @@ -0,0 +1,66 @@ +// Copyright 2015 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 ( + "database/sql/driver" + "errors" + "fmt" +) + +// Scan implements sql.Scanner so UUIDs can be read from databases transparently +// Currently, database types that map to string and []byte are supported. Please +// consult database-specific driver documentation for matching types. +func (uuid *UUID) Scan(src interface{}) error { + switch src.(type) { + case string: + // if an empty UUID comes from a table, we return a null UUID + if src.(string) == "" { + return nil + } + + // see uuid.Parse for required string format + parsed := Parse(src.(string)) + + if parsed == nil { + return errors.New("Scan: invalid UUID format") + } + + *uuid = parsed + case []byte: + b := src.([]byte) + + // if an empty UUID comes from a table, we return a null UUID + if len(b) == 0 { + return nil + } + + // assumes a simple slice of bytes if 16 bytes + // otherwise attempts to parse + if len(b) == 16 { + *uuid = UUID(b) + } else { + u := Parse(string(b)) + + if u == nil { + return errors.New("Scan: invalid UUID format") + } + + *uuid = u + } + + default: + return fmt.Errorf("Scan: unable to scan type %T into UUID", src) + } + + return nil +} + +// Value implements sql.Valuer so that UUIDs can be written to databases +// transparently. Currently, UUIDs map to strings. Please consult +// database-specific driver documentation for matching types. +func (uuid UUID) Value() (driver.Value, error) { + return uuid.String(), nil +} diff --git a/vendor/github.com/pborman/uuid/time.go b/vendor/github.com/pborman/uuid/time.go new file mode 100644 index 000000000..eedf24219 --- /dev/null +++ b/vendor/github.com/pborman/uuid/time.go @@ -0,0 +1,132 @@ +// 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 ( + timeMu 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 timeMu.Unlock() + timeMu.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 timeMu.Unlock() + timeMu.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 timeMu.Unlock() + timeMu.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 +} diff --git a/vendor/github.com/pborman/uuid/util.go b/vendor/github.com/pborman/uuid/util.go new file mode 100644 index 000000000..fc8e052c7 --- /dev/null +++ b/vendor/github.com/pborman/uuid/util.go @@ -0,0 +1,43 @@ +// 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 = [256]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 +} diff --git a/vendor/github.com/pborman/uuid/uuid.go b/vendor/github.com/pborman/uuid/uuid.go new file mode 100644 index 000000000..7c643cf0a --- /dev/null +++ b/vendor/github.com/pborman/uuid/uuid.go @@ -0,0 +1,201 @@ +// 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" + "encoding/hex" + "fmt" + "io" + "strings" +) + +// Array is a pass-by-value UUID that can be used as an effecient key in a map. +type Array [16]byte + +// UUID converts uuid into a slice. +func (uuid Array) UUID() UUID { + return uuid[:] +} + +// String returns the string representation of uuid, +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (uuid Array) String() string { + return uuid.UUID().String() +} + +// 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 + } + var uuid [16]byte + for i, x := range [16]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) +} + +// Array returns an array representation of uuid that can be used as a map key. +// Array panics if uuid is not valid. +func (uuid UUID) Array() Array { + if len(uuid) != 16 { + panic("invalid uuid") + } + var a Array + copy(a[:], uuid) + return a +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + if len(uuid) != 16 { + return "" + } + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// 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 len(uuid) != 16 { + return "" + } + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst[:], uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[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 + } +} + +// Version returns the version 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 implements 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 +} diff --git a/vendor/github.com/pborman/uuid/version1.go b/vendor/github.com/pborman/uuid/version1.go new file mode 100644 index 000000000..0127eacfa --- /dev/null +++ b/vendor/github.com/pborman/uuid/version1.go @@ -0,0 +1,41 @@ +// 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 +} diff --git a/vendor/github.com/pborman/uuid/version4.go b/vendor/github.com/pborman/uuid/version4.go new file mode 100644 index 000000000..b3d4a368d --- /dev/null +++ b/vendor/github.com/pborman/uuid/version4.go @@ -0,0 +1,25 @@ +// 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 +}