1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #17089 from Microsoft/10662-ansi

Windows: Native ANSI console support
This commit is contained in:
Alexander Morozov 2015-11-09 08:05:08 -08:00
commit 28588efb47
3 changed files with 91 additions and 10 deletions

View file

@ -3,13 +3,13 @@ package daemon
import (
"fmt"
"os"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/graphdriver"
// register the windows graph driver
_ "github.com/docker/docker/daemon/graphdriver/windows"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/runconfig"
"github.com/docker/libnetwork"
)
@ -62,21 +62,15 @@ func checkConfigOptions(config *Config) error {
// checkSystem validates platform-specific requirements
func checkSystem() error {
var dwVersion uint32
// TODO Windows. May need at some point to ensure have elevation and
// possibly LocalSystem.
// Validate the OS version. Note that docker.exe must be manifested for this
// call to return the correct version.
dwVersion, err := syscall.GetVersion()
osv, err := system.GetOSVersion()
if err != nil {
return fmt.Errorf("Failed to call GetVersion()")
return err
}
if int(dwVersion&0xFF) < 10 {
if osv.MajorVersion < 10 {
return fmt.Errorf("This version of Windows does not support the docker daemon")
}
return nil
}

View file

@ -1,5 +1,34 @@
package system
import (
"fmt"
"syscall"
)
// OSVersion is a wrapper for Windows version information
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
type OSVersion struct {
Version uint32
MajorVersion uint8
MinorVersion uint8
Build uint16
}
// GetOSVersion gets the operating system version on Windows. Note that
// docker.exe must be manifested to get the correct version information.
func GetOSVersion() (OSVersion, error) {
var err error
osv := OSVersion{}
osv.Version, err = syscall.GetVersion()
if err != nil {
return osv, fmt.Errorf("Failed to call GetVersion()")
}
osv.MajorVersion = uint8(osv.Version & 0xFF)
osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF)
osv.Build = uint16(osv.Version >> 16)
return osv, nil
}
// Unmount is a platform-specific helper function to call
// the unmount syscall. Not supported on Windows
func Unmount(dest string) error {

View file

@ -7,9 +7,11 @@ import (
"io"
"os"
"os/signal"
"syscall"
"github.com/Azure/go-ansiterm/winterm"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/term/windows"
)
@ -36,10 +38,66 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
// MSYS (mingw) does not emulate ANSI well.
return windows.ConsoleStreams()
default:
if useNativeConsole() {
return os.Stdin, os.Stdout, os.Stderr
}
return windows.ConsoleStreams()
}
}
// useNativeConsole determines if the docker client should use the built-in
// console which supports ANSI emulation, or fall-back to the golang emulator
// (github.com/azure/go-ansiterm).
func useNativeConsole() bool {
osv, err := system.GetOSVersion()
if err != nil {
return false
}
// Native console is not available major version 10
if osv.MajorVersion < 10 {
return false
}
// Must have a late pre-release TP4 build of Windows Server 2016/Windows 10 TH2 or later
if osv.Build < 10578 {
return false
}
// Environment variable override
if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" {
if e == "1" {
return true
}
return false
}
// Get the handle to stdout
stdOutHandle, err := syscall.GetStdHandle(syscall.STD_OUTPUT_HANDLE)
if err != nil {
return false
}
// Get the console mode from the consoles stdout handle
var mode uint32
if err := syscall.GetConsoleMode(stdOutHandle, &mode); err != nil {
return false
}
// Legacy mode does not have native ANSI emulation.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
const enableVirtualTerminalProcessing = 0x0004
if mode&enableVirtualTerminalProcessing == 0 {
return false
}
// TODO Windows (Post TP4). The native emulator still has issues which
// mean it shouldn't be enabled for everyone. Change this next line to true
// to change the default to "enable if available". In the meantime, users
// can still try it out by using USE_NATIVE_CONSOLE env variable.
return false
}
// GetFdInfo returns the file descriptor for an os.File and indicates whether the file represents a terminal.
func GetFdInfo(in interface{}) (uintptr, bool) {
return windows.GetHandleInfo(in)