Browse code

Windows: Impl pkg\parsers kernel+os

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2015/05/09 06:59:38
Showing 6 changed files
... ...
@@ -1,3 +1,5 @@
1
+// +build !windows
2
+
1 3
 package kernel
2 4
 
3 5
 import (
4 6
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+package kernel
1
+
2
+import (
3
+	"fmt"
4
+	"syscall"
5
+	"unsafe"
6
+)
7
+
8
+type KernelVersionInfo struct {
9
+	kvi   string
10
+	major int
11
+	minor int
12
+	build int
13
+}
14
+
15
+func (k *KernelVersionInfo) String() string {
16
+	return fmt.Sprintf("%d.%d %d (%s)", k.major, k.minor, k.build, k.kvi)
17
+}
18
+
19
+func GetKernelVersion() (*KernelVersionInfo, error) {
20
+
21
+	var (
22
+		h         syscall.Handle
23
+		dwVersion uint32
24
+		err       error
25
+	)
26
+
27
+	KVI := &KernelVersionInfo{"Unknown", 0, 0, 0}
28
+
29
+	if err = syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
30
+		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
31
+		0,
32
+		syscall.KEY_READ,
33
+		&h); err != nil {
34
+		return KVI, err
35
+	}
36
+	defer syscall.RegCloseKey(h)
37
+
38
+	var buf [1 << 10]uint16
39
+	var typ uint32
40
+	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
41
+
42
+	if err = syscall.RegQueryValueEx(h,
43
+		syscall.StringToUTF16Ptr("BuildLabEx"),
44
+		nil,
45
+		&typ,
46
+		(*byte)(unsafe.Pointer(&buf[0])),
47
+		&n); err != nil {
48
+		return KVI, err
49
+	}
50
+
51
+	KVI.kvi = syscall.UTF16ToString(buf[:])
52
+
53
+	// Important - docker.exe MUST be manifested for this API to return
54
+	// the correct information.
55
+	if dwVersion, err = syscall.GetVersion(); err != nil {
56
+		return KVI, err
57
+	}
58
+
59
+	KVI.major = int(dwVersion & 0xFF)
60
+	KVI.minor = int((dwVersion & 0XFF00) >> 8)
61
+	KVI.build = int((dwVersion & 0xFFFF0000) >> 16)
62
+
63
+	return KVI, nil
64
+}
0 65
deleted file mode 100644
... ...
@@ -1,40 +0,0 @@
1
-package operatingsystem
2
-
3
-import (
4
-	"bytes"
5
-	"errors"
6
-	"io/ioutil"
7
-)
8
-
9
-var (
10
-	// file to use to detect if the daemon is running in a container
11
-	proc1Cgroup = "/proc/1/cgroup"
12
-
13
-	// file to check to determine Operating System
14
-	etcOsRelease = "/etc/os-release"
15
-)
16
-
17
-func GetOperatingSystem() (string, error) {
18
-	b, err := ioutil.ReadFile(etcOsRelease)
19
-	if err != nil {
20
-		return "", err
21
-	}
22
-	if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 {
23
-		b = b[i+13:]
24
-		return string(b[:bytes.IndexByte(b, '"')]), nil
25
-	}
26
-	return "", errors.New("PRETTY_NAME not found")
27
-}
28
-
29
-func IsContainerized() (bool, error) {
30
-	b, err := ioutil.ReadFile(proc1Cgroup)
31
-	if err != nil {
32
-		return false, err
33
-	}
34
-	for _, line := range bytes.Split(b, []byte{'\n'}) {
35
-		if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) {
36
-			return true, nil
37
-		}
38
-	}
39
-	return false, nil
40
-}
41 1
new file mode 100644
... ...
@@ -0,0 +1,40 @@
0
+package operatingsystem
1
+
2
+import (
3
+	"bytes"
4
+	"errors"
5
+	"io/ioutil"
6
+)
7
+
8
+var (
9
+	// file to use to detect if the daemon is running in a container
10
+	proc1Cgroup = "/proc/1/cgroup"
11
+
12
+	// file to check to determine Operating System
13
+	etcOsRelease = "/etc/os-release"
14
+)
15
+
16
+func GetOperatingSystem() (string, error) {
17
+	b, err := ioutil.ReadFile(etcOsRelease)
18
+	if err != nil {
19
+		return "", err
20
+	}
21
+	if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 {
22
+		b = b[i+13:]
23
+		return string(b[:bytes.IndexByte(b, '"')]), nil
24
+	}
25
+	return "", errors.New("PRETTY_NAME not found")
26
+}
27
+
28
+func IsContainerized() (bool, error) {
29
+	b, err := ioutil.ReadFile(proc1Cgroup)
30
+	if err != nil {
31
+		return false, err
32
+	}
33
+	for _, line := range bytes.Split(b, []byte{'\n'}) {
34
+		if len(line) > 0 && !bytes.HasSuffix(line, []byte{'/'}) {
35
+			return true, nil
36
+		}
37
+	}
38
+	return false, nil
39
+}
0 40
new file mode 100644
... ...
@@ -0,0 +1,47 @@
0
+package operatingsystem
1
+
2
+import (
3
+	"syscall"
4
+	"unsafe"
5
+)
6
+
7
+// See https://code.google.com/p/go/source/browse/src/pkg/mime/type_windows.go?r=d14520ac25bf6940785aabb71f5be453a286f58c
8
+// for a similar sample
9
+
10
+func GetOperatingSystem() (string, error) {
11
+
12
+	var h syscall.Handle
13
+
14
+	// Default return value
15
+	ret := "Unknown Operating System"
16
+
17
+	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE,
18
+		syscall.StringToUTF16Ptr(`SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\`),
19
+		0,
20
+		syscall.KEY_READ,
21
+		&h); err != nil {
22
+		return ret, err
23
+	}
24
+	defer syscall.RegCloseKey(h)
25
+
26
+	var buf [1 << 10]uint16
27
+	var typ uint32
28
+	n := uint32(len(buf) * 2) // api expects array of bytes, not uint16
29
+
30
+	if err := syscall.RegQueryValueEx(h,
31
+		syscall.StringToUTF16Ptr("ProductName"),
32
+		nil,
33
+		&typ,
34
+		(*byte)(unsafe.Pointer(&buf[0])),
35
+		&n); err != nil {
36
+		return ret, err
37
+	}
38
+	ret = syscall.UTF16ToString(buf[:])
39
+
40
+	return ret, nil
41
+}
42
+
43
+// No-op on Windows
44
+func IsContainerized() (bool, error) {
45
+	return false, nil
46
+}
... ...
@@ -2,6 +2,7 @@ package parsers
2 2
 
3 3
 import (
4 4
 	"fmt"
5
+	"runtime"
5 6
 	"strconv"
6 7
 	"strings"
7 8
 )
... ...
@@ -10,7 +11,12 @@ import (
10 10
 func ParseHost(defaultTCPAddr, defaultUnixAddr, addr string) (string, error) {
11 11
 	addr = strings.TrimSpace(addr)
12 12
 	if addr == "" {
13
-		addr = fmt.Sprintf("unix://%s", defaultUnixAddr)
13
+		if runtime.GOOS != "windows" {
14
+			addr = fmt.Sprintf("unix://%s", defaultUnixAddr)
15
+		} else {
16
+			// Note - defaultTCPAddr already includes tcp:// prefix
17
+			addr = fmt.Sprintf("%s", defaultTCPAddr)
18
+		}
14 19
 	}
15 20
 	addrParts := strings.Split(addr, "://")
16 21
 	if len(addrParts) == 1 {