Signed-off-by: John Howard <jhoward@microsoft.com>
John Howard authored on 2015/10/16 03:40:14... | ... |
@@ -3,13 +3,13 @@ package daemon |
3 | 3 |
import ( |
4 | 4 |
"fmt" |
5 | 5 |
"os" |
6 |
- "syscall" |
|
7 | 6 |
|
8 | 7 |
"github.com/Sirupsen/logrus" |
9 | 8 |
"github.com/docker/docker/daemon/graphdriver" |
10 | 9 |
// register the windows graph driver |
11 | 10 |
_ "github.com/docker/docker/daemon/graphdriver/windows" |
12 | 11 |
"github.com/docker/docker/pkg/parsers" |
12 |
+ "github.com/docker/docker/pkg/system" |
|
13 | 13 |
"github.com/docker/docker/runconfig" |
14 | 14 |
"github.com/docker/libnetwork" |
15 | 15 |
) |
... | ... |
@@ -62,21 +62,15 @@ func checkConfigOptions(config *Config) error { |
62 | 62 |
|
63 | 63 |
// checkSystem validates platform-specific requirements |
64 | 64 |
func checkSystem() error { |
65 |
- var dwVersion uint32 |
|
66 |
- |
|
67 |
- // TODO Windows. May need at some point to ensure have elevation and |
|
68 |
- // possibly LocalSystem. |
|
69 |
- |
|
70 | 65 |
// Validate the OS version. Note that docker.exe must be manifested for this |
71 | 66 |
// call to return the correct version. |
72 |
- dwVersion, err := syscall.GetVersion() |
|
67 |
+ osv, err := system.GetOSVersion() |
|
73 | 68 |
if err != nil { |
74 |
- return fmt.Errorf("Failed to call GetVersion()") |
|
69 |
+ return err |
|
75 | 70 |
} |
76 |
- if int(dwVersion&0xFF) < 10 { |
|
71 |
+ if osv.MajorVersion < 10 { |
|
77 | 72 |
return fmt.Errorf("This version of Windows does not support the docker daemon") |
78 | 73 |
} |
79 |
- |
|
80 | 74 |
return nil |
81 | 75 |
} |
82 | 76 |
|
... | ... |
@@ -1,5 +1,34 @@ |
1 | 1 |
package system |
2 | 2 |
|
3 |
+import ( |
|
4 |
+ "fmt" |
|
5 |
+ "syscall" |
|
6 |
+) |
|
7 |
+ |
|
8 |
+// OSVersion is a wrapper for Windows version information |
|
9 |
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx |
|
10 |
+type OSVersion struct { |
|
11 |
+ Version uint32 |
|
12 |
+ MajorVersion uint8 |
|
13 |
+ MinorVersion uint8 |
|
14 |
+ Build uint16 |
|
15 |
+} |
|
16 |
+ |
|
17 |
+// GetOSVersion gets the operating system version on Windows. Note that |
|
18 |
+// docker.exe must be manifested to get the correct version information. |
|
19 |
+func GetOSVersion() (OSVersion, error) { |
|
20 |
+ var err error |
|
21 |
+ osv := OSVersion{} |
|
22 |
+ osv.Version, err = syscall.GetVersion() |
|
23 |
+ if err != nil { |
|
24 |
+ return osv, fmt.Errorf("Failed to call GetVersion()") |
|
25 |
+ } |
|
26 |
+ osv.MajorVersion = uint8(osv.Version & 0xFF) |
|
27 |
+ osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF) |
|
28 |
+ osv.Build = uint16(osv.Version >> 16) |
|
29 |
+ return osv, nil |
|
30 |
+} |
|
31 |
+ |
|
3 | 32 |
// Unmount is a platform-specific helper function to call |
4 | 33 |
// the unmount syscall. Not supported on Windows |
5 | 34 |
func Unmount(dest string) { |
... | ... |
@@ -7,9 +7,11 @@ import ( |
7 | 7 |
"io" |
8 | 8 |
"os" |
9 | 9 |
"os/signal" |
10 |
+ "syscall" |
|
10 | 11 |
|
11 | 12 |
"github.com/Azure/go-ansiterm/winterm" |
12 | 13 |
"github.com/Sirupsen/logrus" |
14 |
+ "github.com/docker/docker/pkg/system" |
|
13 | 15 |
"github.com/docker/docker/pkg/term/windows" |
14 | 16 |
) |
15 | 17 |
|
... | ... |
@@ -36,10 +38,66 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) { |
36 | 36 |
// MSYS (mingw) does not emulate ANSI well. |
37 | 37 |
return windows.ConsoleStreams() |
38 | 38 |
default: |
39 |
+ if useNativeConsole() { |
|
40 |
+ return os.Stdin, os.Stdout, os.Stderr |
|
41 |
+ } |
|
39 | 42 |
return windows.ConsoleStreams() |
40 | 43 |
} |
41 | 44 |
} |
42 | 45 |
|
46 |
+// useNativeConsole determines if the docker client should use the built-in |
|
47 |
+// console which supports ANSI emulation, or fall-back to the golang emulator |
|
48 |
+// (github.com/azure/go-ansiterm). |
|
49 |
+func useNativeConsole() bool { |
|
50 |
+ osv, err := system.GetOSVersion() |
|
51 |
+ if err != nil { |
|
52 |
+ return false |
|
53 |
+ } |
|
54 |
+ |
|
55 |
+ // Native console is not available major version 10 |
|
56 |
+ if osv.MajorVersion < 10 { |
|
57 |
+ return false |
|
58 |
+ } |
|
59 |
+ |
|
60 |
+ // Must have a late pre-release TP4 build of Windows Server 2016/Windows 10 TH2 or later |
|
61 |
+ if osv.Build < 10578 { |
|
62 |
+ return false |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ // Environment variable override |
|
66 |
+ if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" { |
|
67 |
+ if e == "1" { |
|
68 |
+ return true |
|
69 |
+ } |
|
70 |
+ return false |
|
71 |
+ } |
|
72 |
+ |
|
73 |
+ // Get the handle to stdout |
|
74 |
+ stdOutHandle, err := syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE) |
|
75 |
+ if err != nil { |
|
76 |
+ return false |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ // Get the console mode from the consoles stdout handle |
|
80 |
+ var mode uint32 |
|
81 |
+ if err := syscall.GetConsoleMode(stdOutHandle, &mode); err != nil { |
|
82 |
+ return false |
|
83 |
+ } |
|
84 |
+ |
|
85 |
+ // Legacy mode does not have native ANSI emulation. |
|
86 |
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx |
|
87 |
+ const enableVirtualTerminalProcessing = 0x0004 |
|
88 |
+ if mode&enableVirtualTerminalProcessing == 0 { |
|
89 |
+ return false |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ // TODO Windows (Post TP4). The native emulator still has issues which |
|
93 |
+ // mean it shouldn't be enabled for everyone. Change this next line to true |
|
94 |
+ // to change the default to "enable if available". In the meantime, users |
|
95 |
+ // can still try it out by using USE_NATIVE_CONSOLE env variable. |
|
96 |
+ return false |
|
97 |
+} |
|
98 |
+ |
|
43 | 99 |
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal. |
44 | 100 |
func GetFdInfo(in interface{}) (uintptr, bool) { |
45 | 101 |
return windows.GetHandleInfo(in) |