Merge pull request #2279 from hashicorp/f-windows-hostid

Add durable HostID generation support to Windows.
This commit is contained in:
Alex Dadgar
2017-02-02 17:03:55 -08:00
committed by GitHub
3 changed files with 79 additions and 19 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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(&regBuf[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