// 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 := system.GetOSVersion() // Native console is not available before major version 10 if osv.MajorVersion < 10 { return false } // Get the console modes. If this fails, we can't use the native console state, err := getNativeConsole() if err != nil { return false } // Probe the console to see if it can be enabled. if nil != probeNativeConsole(state) { return false } // Environment variable override if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" { if e == "1" { return true } return false } // Must have a post-TP5 RS1 build of Windows Server 2016/Windows 10 for // the native console to be usable. if osv.Build < 14350 { return false } return true }
// 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 := system.GetOSVersion() // Native console is not available before major version 10 if osv.MajorVersion < 10 { return false } // Get the console modes. If this fails, we can't use the native console state, err := getNativeConsole() if err != nil { return false } // Probe the console to see if it can be enabled. if nil != probeNativeConsole(state) { return false } // Environment variable override if e := os.Getenv("USE_NATIVE_CONSOLE"); e != "" { if e == "1" { return true } return false } // TODO Windows. 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 }
// checkSystem validates platform-specific requirements func checkSystem() error { // Validate the OS version. Note that docker.exe must be manifested for this // call to return the correct version. osv := system.GetOSVersion() if osv.MajorVersion < 10 { return fmt.Errorf("This version of Windows does not support the docker daemon") } if osv.Build < 14300 { return fmt.Errorf("The Windows daemon requires Windows Server 2016 Technical Preview 5 build 14300 or later") } return nil }
func init() { osv := system.GetOSVersion() // Read-only volumes supported from 14350 onwards (post Windows Server 2016 TP5) // Mode (optional): // - Hopefully self explanatory in comparison to above regex's. // - Colon is not in the capture group if osv.Build >= 14350 { RXMode = `(:(?P<mode>(?i)ro|rw))?` } else { RXMode = `(:(?P<mode>(?i)rw))?` } }
// checkSystem validates platform-specific requirements func checkSystem() error { // Validate the OS version. Note that docker.exe must be manifested for this // call to return the correct version. osv, err := system.GetOSVersion() if err != nil { return err } if osv.MajorVersion < 10 { return fmt.Errorf("This version of Windows does not support the docker daemon") } return nil }
// 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 }
// checkSystem validates platform-specific requirements func checkSystem() error { // Validate the OS version. Note that docker.exe must be manifested for this // call to return the correct version. osv := system.GetOSVersion() if osv.MajorVersion < 10 { return fmt.Errorf("This version of Windows does not support the docker daemon") } if osv.Build < 14393 { return fmt.Errorf("The docker daemon requires build 14393 or later of Windows Server 2016 or Windows 10") } vmcompute := windows.NewLazySystemDLL("vmcompute.dll") if vmcompute.Load() != nil { return fmt.Errorf("Failed to load vmcompute.dll. Ensure that the Containers role is installed.") } return nil }
func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error { if _, err := controller.NetworkByName(runconfig.DefaultDaemonNetworkMode().NetworkName()); err == nil { return nil } netOption := map[string]string{ winlibnetwork.NetworkName: runconfig.DefaultDaemonNetworkMode().NetworkName(), } var ipamOption libnetwork.NetworkOption var subnetPrefix string if config.bridgeConfig.FixedCIDR != "" { subnetPrefix = config.bridgeConfig.FixedCIDR } else { // TP5 doesn't support properly detecting subnet osv := system.GetOSVersion() if osv.Build < 14360 { subnetPrefix = defaultNetworkSpace } } if subnetPrefix != "" { ipamV4Conf := libnetwork.IpamConf{} ipamV4Conf.PreferredPool = subnetPrefix v4Conf := []*libnetwork.IpamConf{&ipamV4Conf} v6Conf := []*libnetwork.IpamConf{} ipamOption = libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil) } _, err := controller.NewNetwork(string(runconfig.DefaultDaemonNetworkMode()), runconfig.DefaultDaemonNetworkMode().NetworkName(), "", libnetwork.NetworkOptionGeneric(options.Generic{ netlabel.GenericData: netOption, }), ipamOption, ) if err != nil { return fmt.Errorf("Error creating default network: %v", err) } return nil }
// fixStdinBackspaceBehavior works around a bug in Windows before build 14350 // where it interpreted DEL as VK_DELETE instead of as VK_BACK. This replaces // DEL with BS to work around this. func fixStdinBackspaceBehavior(w io.WriteCloser, tty bool) io.WriteCloser { if !tty || system.GetOSVersion().Build >= 14350 { return w } return &delToBsWriter{w} }
func isTP5OrOlder() bool { return system.GetOSVersion().Build <= 14300 }
func (daemon *Daemon) initNetworkController(config *Config) (libnetwork.NetworkController, error) { // TODO Windows: Remove this check once TP4 is no longer supported osv, err := system.GetOSVersion() if err != nil { return nil, err } if osv.Build < 14260 { // Set the name of the virtual switch if not specified by -b on daemon start if config.bridgeConfig.Iface == "" { config.bridgeConfig.Iface = defaultVirtualSwitch } logrus.Warnf("Network controller is not supported by the current platform build version") return nil, nil } netOptions, err := daemon.networkOptions(config) if err != nil { return nil, err } controller, err := libnetwork.New(netOptions...) if err != nil { return nil, fmt.Errorf("error obtaining controller instance: %v", err) } hnsresponse, err := hcsshim.HNSListNetworkRequest("GET", "", "") if err != nil { return nil, err } // Remove networks not present in HNS for _, v := range controller.Networks() { options := v.Info().DriverOptions() hnsid := options[winlibnetwork.HNSID] found := false for _, v := range hnsresponse { if v.Id == hnsid { found = true break } } if !found { err = v.Delete() if err != nil { return nil, err } } } _, err = controller.NewNetwork("null", "none", libnetwork.NetworkOptionPersist(false)) if err != nil { return nil, err } // discover and add HNS networks to windows // network that exist are removed and added again for _, v := range hnsresponse { var n libnetwork.Network s := func(current libnetwork.Network) bool { options := current.Info().DriverOptions() if options[winlibnetwork.HNSID] == v.Id { n = current return true } return false } controller.WalkNetworks(s) if n != nil { v.Name = n.Name() n.Delete() } netOption := map[string]string{ winlibnetwork.NetworkName: v.Name, winlibnetwork.HNSID: v.Id, } v4Conf := []*libnetwork.IpamConf{} for _, subnet := range v.Subnets { ipamV4Conf := libnetwork.IpamConf{} ipamV4Conf.PreferredPool = subnet.AddressPrefix ipamV4Conf.Gateway = subnet.GatewayAddress v4Conf = append(v4Conf, &ipamV4Conf) } name := v.Name // There is only one nat network supported in windows. // If it exists with a different name add it as the default name if runconfig.DefaultDaemonNetworkMode() == containertypes.NetworkMode(strings.ToLower(v.Type)) { name = runconfig.DefaultDaemonNetworkMode().NetworkName() } v6Conf := []*libnetwork.IpamConf{} _, err := controller.NewNetwork(strings.ToLower(v.Type), name, libnetwork.NetworkOptionGeneric(options.Generic{ netlabel.GenericData: netOption, }), libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf, nil), ) if err != nil { logrus.Errorf("Error occurred when creating network %v", err) } } if !config.DisableBridge { // Initialize default driver "bridge" if err := initBridgeDriver(controller, config); err != nil { return nil, err } } return controller, nil }
func getOSVersion() string { v := system.GetOSVersion() return fmt.Sprintf("%d.%d.%d", v.MajorVersion, v.MinorVersion, v.Build) }