diff --git a/client/client.go b/client/client.go index 3ad8f07bd..16b3ac401 100644 --- a/client/client.go +++ b/client/client.go @@ -27,6 +27,7 @@ import ( "github.com/hashicorp/nomad/client/stats" "github.com/hashicorp/nomad/client/vaultclient" "github.com/hashicorp/nomad/command/agent/consul" + "github.com/hashicorp/nomad/helper" "github.com/hashicorp/nomad/helper/tlsutil" "github.com/hashicorp/nomad/nomad" "github.com/hashicorp/nomad/nomad/structs" @@ -636,7 +637,7 @@ func (c *Client) getAllocRunners() map[string]*AllocRunner { func (c *Client) nodeID() (id, secret string, err error) { var hostID string hostInfo, err := host.Info() - if err == nil && hostInfo.HostID != "" { + if err == nil && helper.IsUUID(hostInfo.HostID) { hostID = hostInfo.HostID } else { // Generate a random hostID if no constant ID is available on diff --git a/helper/funcs.go b/helper/funcs.go index 653c3a100..89538f42c 100644 --- a/helper/funcs.go +++ b/helper/funcs.go @@ -1,5 +1,20 @@ package helper +import "regexp" + +// validUUID is used to check if a given string looks like a UUID +var validUUID = regexp.MustCompile(`(?i)^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$`) + +// IsUUID returns true if the given string is a valid UUID. +func IsUUID(str string) bool { + const uuidLen = 36 + if len(str) != uuidLen { + return false + } + + return validUUID.MatchString(str) +} + // boolToPtr returns the pointer to a boolean func BoolToPtr(b bool) *bool { return &b diff --git a/vendor/github.com/shirou/gopsutil/host/host_windows.go b/vendor/github.com/shirou/gopsutil/host/host_windows.go index f983a4f29..a689d4784 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_windows.go +++ b/vendor/github.com/shirou/gopsutil/host/host_windows.go @@ -7,7 +7,9 @@ import ( "os" "runtime" "strings" + "syscall" "time" + "unsafe" "github.com/StackExchange/wmi" @@ -33,34 +35,77 @@ func Info() (*InfoStat, error) { OS: runtime.GOOS, } - hostname, err := os.Hostname() - if err == nil { - ret.Hostname = hostname + { + hostname, err := os.Hostname() + if err == nil { + ret.Hostname = hostname + } } - platform, family, version, err := PlatformInformation() - if err == nil { - ret.Platform = platform - ret.PlatformFamily = family - ret.PlatformVersion = version - } else { - return ret, err + { + platform, family, version, err := PlatformInformation() + if err == nil { + ret.Platform = platform + ret.PlatformFamily = family + ret.PlatformVersion = version + } else { + return ret, err + } } - boot, err := BootTime() - if err == nil { - ret.BootTime = boot - ret.Uptime, _ = Uptime() + { + boot, err := BootTime() + if err == nil { + ret.BootTime = boot + ret.Uptime, _ = Uptime() + } } - procs, err := process.Pids() - if err == nil { - ret.Procs = uint64(len(procs)) + { + hostID, err := getMachineGuid() + if err == nil { + ret.HostID = hostID + } + } + + { + procs, err := process.Pids() + if err == nil { + ret.Procs = uint64(len(procs)) + } } return ret, nil } +func getMachineGuid() (string, error) { + var h syscall.Handle + err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, syscall.StringToUTF16Ptr(`SOFTWARE\Microsoft\Cryptography`), 0, syscall.KEY_READ, &h) + if err != nil { + return "", err + } + defer syscall.RegCloseKey(h) + + const windowsRegBufLen = 74 // len(`{`) + len(`abcdefgh-1234-456789012-123345456671` * 2) + len(`}`) // 2 == bytes/UTF16 + const uuidLen = 36 + + var regBuf [windowsRegBufLen]uint16 + bufLen := uint32(windowsRegBufLen) + var valType uint32 + err = syscall.RegQueryValueEx(h, syscall.StringToUTF16Ptr(`MachineGuid`), nil, &valType, (*byte)(unsafe.Pointer(®Buf[0])), &bufLen) + if err != nil { + return "", err + } + + hostID := syscall.UTF16ToString(regBuf[:]) + hostIDLen := len(hostID) + if hostIDLen != uuidLen { + return "", fmt.Errorf("HostID incorrect: %q\n", hostID) + } + + return hostID, nil +} + func GetOSInfo() (Win32_OperatingSystem, error) { var dst []Win32_OperatingSystem q := wmi.CreateQuery(&dst, "") @@ -130,7 +175,6 @@ func PlatformInformation() (platform string, family string, version string, err } func Users() ([]UserStat, error) { - var ret []UserStat return ret, nil