mirror of https://github.com/docker/docs.git
Merge pull request #21809 from Microsoft/jjh/tp4removal
Windows: Remove TP4 support from main codebase
This commit is contained in:
commit
65464d11f1
|
@ -1,24 +1,11 @@
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package dockerfile
|
package dockerfile
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
// platformSupports is gives users a quality error message if a Dockerfile uses
|
||||||
)
|
// a command not supported on the platform.
|
||||||
|
|
||||||
// platformSupports is a short-term function to give users a quality error
|
|
||||||
// message if a Dockerfile uses a command not supported on the platform.
|
|
||||||
func platformSupports(command string) error {
|
func platformSupports(command string) error {
|
||||||
switch command {
|
switch command {
|
||||||
// TODO Windows TP5. Expose can be removed from here once TP4 is
|
|
||||||
// no longer supported.
|
|
||||||
case "expose":
|
|
||||||
if !hcsshim.IsTP4() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case "user", "stopsignal", "arg":
|
case "user", "stopsignal", "arg":
|
||||||
return fmt.Errorf("The daemon on this platform does not support the command '%s'", command)
|
return fmt.Errorf("The daemon on this platform does not support the command '%s'", command)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import "github.com/docker/docker/container"
|
||||||
// cannot be configured with a read-only rootfs.
|
// cannot be configured with a read-only rootfs.
|
||||||
//
|
//
|
||||||
// This is a no-op on Windows which does not support read-only volumes, or
|
// This is a no-op on Windows which does not support read-only volumes, or
|
||||||
// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP4
|
// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP5
|
||||||
func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
|
func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,13 +322,6 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO Windows: Remove this once TP4 builds are not supported
|
|
||||||
// Windows TP4 build don't support libnetwork and in that case
|
|
||||||
// daemon.netController will be nil
|
|
||||||
if daemon.netController == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mode := container.HostConfig.NetworkMode
|
mode := container.HostConfig.NetworkMode
|
||||||
if container.Config.NetworkDisabled || mode.IsContainer() {
|
if container.Config.NetworkDisabled || mode.IsContainer() {
|
||||||
return nil
|
return nil
|
||||||
|
@ -511,13 +504,6 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrNa
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) {
|
func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) {
|
||||||
// TODO Windows: Remove this once TP4 builds are not supported
|
|
||||||
// Windows TP4 build don't support libnetwork and in that case
|
|
||||||
// daemon.netController will be nil
|
|
||||||
if daemon.netController == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, updateSettings)
|
n, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, updateSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -644,13 +630,6 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network,
|
||||||
func (daemon *Daemon) initializeNetworking(container *container.Container) error {
|
func (daemon *Daemon) initializeNetworking(container *container.Container) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// TODO Windows: Remove this once TP4 builds are not supported
|
|
||||||
// Windows TP4 build don't support libnetwork and in that case
|
|
||||||
// daemon.netController will be nil
|
|
||||||
if daemon.netController == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if container.HostConfig.NetworkMode.IsContainer() {
|
if container.HostConfig.NetworkMode.IsContainer() {
|
||||||
// we need to get the hosts files from the container to join
|
// we need to get the hosts files from the container to join
|
||||||
nc, err := daemon.getNetworkedContainer(container.ID, container.HostConfig.NetworkMode.ConnectedContainer())
|
nc, err := daemon.getNetworkedContainer(container.ID, container.HostConfig.NetworkMode.ConnectedContainer())
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Windows: Fix Post-TP4. This is a hack to allow docker cp to work
|
// TODO Windows: Fix Post-TP5. This is a hack to allow docker cp to work
|
||||||
// against containers which have volumes. You will still be able to cp
|
// against containers which have volumes. You will still be able to cp
|
||||||
// to somewhere on the container drive, but not to any mounted volumes
|
// to somewhere on the container drive, but not to any mounted volumes
|
||||||
// inside the container. Without this fix, docker cp is broken to any
|
// inside the container. Without this fix, docker cp is broken to any
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain
|
||||||
// is deferred for now. A case where this would be useful is when
|
// is deferred for now. A case where this would be useful is when
|
||||||
// a dockerfile includes a VOLUME statement, but something is created
|
// a dockerfile includes a VOLUME statement, but something is created
|
||||||
// in that directory during the dockerfile processing. What this means
|
// in that directory during the dockerfile processing. What this means
|
||||||
// on Windows for TP4 is that in that scenario, the contents will not
|
// on Windows for TP5 is that in that scenario, the contents will not
|
||||||
// copied, but that's (somewhat) OK as HCS will bomb out soon after
|
// copied, but that's (somewhat) OK as HCS will bomb out soon after
|
||||||
// at it doesn't support mapped directories which have contents in the
|
// at it doesn't support mapped directories which have contents in the
|
||||||
// destination path anyway.
|
// destination path anyway.
|
||||||
|
|
|
@ -506,34 +506,6 @@ func writeTarFromLayer(r hcsshim.LayerReader, w io.Writer) error {
|
||||||
|
|
||||||
// exportLayer generates an archive from a layer based on the given ID.
|
// exportLayer generates an archive from a layer based on the given ID.
|
||||||
func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) {
|
func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) {
|
||||||
if hcsshim.IsTP4() {
|
|
||||||
// Export in TP4 format to maintain compatibility with existing images and
|
|
||||||
// because ExportLayer is somewhat broken on TP4 and can't work with the new
|
|
||||||
// scheme.
|
|
||||||
tempFolder, err := ioutil.TempDir("", "hcs")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
os.RemoveAll(tempFolder)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err = hcsshim.ExportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
archive, err := archive.Tar(tempFolder, archive.Uncompressed)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ioutils.NewReadCloserWrapper(archive, func() error {
|
|
||||||
err := archive.Close()
|
|
||||||
os.RemoveAll(tempFolder)
|
|
||||||
return err
|
|
||||||
}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var r hcsshim.LayerReader
|
var r hcsshim.LayerReader
|
||||||
r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths)
|
r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -598,24 +570,6 @@ func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter) (int64, error) {
|
||||||
|
|
||||||
// importLayer adds a new layer to the tag and graph store based on the given data.
|
// importLayer adds a new layer to the tag and graph store based on the given data.
|
||||||
func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) {
|
func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) {
|
||||||
if hcsshim.IsTP4() {
|
|
||||||
// Import from TP4 format to maintain compatibility with existing images.
|
|
||||||
var tempFolder string
|
|
||||||
tempFolder, err = ioutil.TempDir("", "hcs")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tempFolder)
|
|
||||||
|
|
||||||
if size, err = chrootarchive.ApplyLayer(tempFolder, layerData); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = hcsshim.ImportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var w hcsshim.LayerWriter
|
var w hcsshim.LayerWriter
|
||||||
w, err = hcsshim.NewLayerWriter(d.info, id, parentLayerPaths)
|
w, err = hcsshim.NewLayerWriter(d.info, id, parentLayerPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -736,31 +690,5 @@ func (d *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if hcsshim.IsTP4() {
|
|
||||||
// The export format for TP4 is different from the contents of the layer, so
|
|
||||||
// fall back to exporting the layer and getting file contents from there.
|
|
||||||
layerChain, err := d.getLayerChain(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tempFolder string
|
|
||||||
tempFolder, err = ioutil.TempDir("", "hcs")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
os.RemoveAll(tempFolder)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if err = hcsshim.ExportLayer(d.info, id, tempFolder, layerChain); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &fileGetDestroyCloser{storage.NewPathFileGetter(tempFolder), tempFolder}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &fileGetCloserWithBackupPrivileges{d.dir(id)}, nil
|
return &fileGetCloserWithBackupPrivileges{d.dir(id)}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/docker/docker/container"
|
"github.com/docker/docker/container"
|
||||||
|
@ -103,7 +102,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
|
||||||
}
|
}
|
||||||
s.Windows.LayerPaths = layerPaths
|
s.Windows.LayerPaths = layerPaths
|
||||||
|
|
||||||
// In s.Windows.Networking (TP5+ libnetwork way of doing things)
|
// In s.Windows.Networking
|
||||||
// Connect all the libnetwork allocated networks to the container
|
// Connect all the libnetwork allocated networks to the container
|
||||||
var epList []string
|
var epList []string
|
||||||
if c.NetworkSettings != nil {
|
if c.NetworkSettings != nil {
|
||||||
|
@ -131,26 +130,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
|
||||||
EndpointList: epList,
|
EndpointList: epList,
|
||||||
}
|
}
|
||||||
|
|
||||||
// In s.Windows.Networking (TP4 back compat)
|
|
||||||
// TODO Windows: Post TP4 - Remove this along with definitions from spec
|
|
||||||
// and changes to libcontainerd to not read these fields.
|
|
||||||
if daemon.netController == nil {
|
|
||||||
parts := strings.SplitN(string(c.HostConfig.NetworkMode), ":", 2)
|
|
||||||
switch parts[0] {
|
|
||||||
case "none":
|
|
||||||
case "default", "": // empty string to support existing containers
|
|
||||||
if !c.Config.NetworkDisabled {
|
|
||||||
s.Windows.Networking = &windowsoci.Networking{
|
|
||||||
MacAddress: c.Config.MacAddress,
|
|
||||||
Bridge: daemon.configStore.bridgeConfig.Iface,
|
|
||||||
PortBindings: c.HostConfig.PortBindings,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid network mode: %s", c.HostConfig.NetworkMode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In s.Windows.Resources
|
// In s.Windows.Resources
|
||||||
// @darrenstahlmsft implement these resources
|
// @darrenstahlmsft implement these resources
|
||||||
cpuShares := uint64(c.HostConfig.CPUShares)
|
cpuShares := uint64(c.HostConfig.CPUShares)
|
||||||
|
|
|
@ -6,11 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Microsoft/hcsshim"
|
"github.com/Microsoft/hcsshim"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
|
@ -22,10 +19,6 @@ type client struct {
|
||||||
// Platform specific properties below here (none presently on Windows)
|
// Platform specific properties below here (none presently on Windows)
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultContainerNAT is the default name of the container NAT device that is
|
|
||||||
// preconfigured on the server. TODO Windows - Remove for TP5 support as not needed.
|
|
||||||
const defaultContainerNAT = "ContainerNAT"
|
|
||||||
|
|
||||||
// Win32 error codes that are used for various workarounds
|
// Win32 error codes that are used for various workarounds
|
||||||
// These really should be ALL_CAPS to match golangs syscall library and standard
|
// These really should be ALL_CAPS to match golangs syscall library and standard
|
||||||
// Win32 error conventions, but golint insists on CamelCase.
|
// Win32 error conventions, but golint insists on CamelCase.
|
||||||
|
@ -190,108 +183,15 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio
|
||||||
}
|
}
|
||||||
cu.MappedDirectories = mds
|
cu.MappedDirectories = mds
|
||||||
|
|
||||||
// TODO Windows: vv START OF TP4 BLOCK OF CODE. REMOVE ONCE TP4 IS NO LONGER SUPPORTED
|
|
||||||
if hcsshim.IsTP4() &&
|
|
||||||
spec.Windows.Networking != nil &&
|
|
||||||
spec.Windows.Networking.Bridge != "" {
|
|
||||||
// Enumerate through the port bindings specified by the user and convert
|
|
||||||
// them into the internal structure matching the JSON blob that can be
|
|
||||||
// understood by the HCS.
|
|
||||||
var pbs []portBinding
|
|
||||||
for i, v := range spec.Windows.Networking.PortBindings {
|
|
||||||
proto := strings.ToUpper(i.Proto())
|
|
||||||
if proto != "TCP" && proto != "UDP" {
|
|
||||||
return fmt.Errorf("invalid protocol %s", i.Proto())
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(v) > 1 {
|
|
||||||
return fmt.Errorf("Windows does not support more than one host port in NAT settings")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v2 := range v {
|
|
||||||
var (
|
|
||||||
iPort, ePort int
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
if len(v2.HostIP) != 0 {
|
|
||||||
return fmt.Errorf("Windows does not support host IP addresses in NAT settings")
|
|
||||||
}
|
|
||||||
if ePort, err = strconv.Atoi(v2.HostPort); err != nil {
|
|
||||||
return fmt.Errorf("invalid container port %s: %s", v2.HostPort, err)
|
|
||||||
}
|
|
||||||
if iPort, err = strconv.Atoi(i.Port()); err != nil {
|
|
||||||
return fmt.Errorf("invalid internal port %s: %s", i.Port(), err)
|
|
||||||
}
|
|
||||||
if iPort < 0 || iPort > 65535 || ePort < 0 || ePort > 65535 {
|
|
||||||
return fmt.Errorf("specified NAT port is not in allowed range")
|
|
||||||
}
|
|
||||||
pbs = append(pbs,
|
|
||||||
portBinding{ExternalPort: ePort,
|
|
||||||
InternalPort: iPort,
|
|
||||||
Protocol: proto})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dev := device{
|
|
||||||
DeviceType: "Network",
|
|
||||||
Connection: &networkConnection{
|
|
||||||
NetworkName: spec.Windows.Networking.Bridge,
|
|
||||||
Nat: natSettings{
|
|
||||||
Name: defaultContainerNAT,
|
|
||||||
PortBindings: pbs,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if spec.Windows.Networking.MacAddress != "" {
|
|
||||||
windowsStyleMAC := strings.Replace(
|
|
||||||
spec.Windows.Networking.MacAddress, ":", "-", -1)
|
|
||||||
dev.Settings = networkSettings{
|
|
||||||
MacAddress: windowsStyleMAC,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cu.Devices = append(cu.Devices, dev)
|
|
||||||
} else {
|
|
||||||
logrus.Debugln("No network interface")
|
|
||||||
}
|
|
||||||
// TODO Windows: ^^ END OF TP4 BLOCK OF CODE. REMOVE ONCE TP4 IS NO LONGER SUPPORTED
|
|
||||||
|
|
||||||
configurationb, err := json.Marshal(cu)
|
configurationb, err := json.Marshal(cu)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the compute system
|
||||||
configuration := string(configurationb)
|
configuration := string(configurationb)
|
||||||
|
if err := hcsshim.CreateComputeSystem(containerID, configuration); err != nil {
|
||||||
// TODO Windows TP5 timeframe. Remove when TP4 is no longer supported.
|
return err
|
||||||
// The following a workaround for Windows TP4 which has a networking
|
|
||||||
// bug which fairly frequently returns an error. Back off and retry.
|
|
||||||
if !hcsshim.IsTP4() {
|
|
||||||
if err := hcsshim.CreateComputeSystem(containerID, configuration); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
maxAttempts := 5
|
|
||||||
for i := 1; i <= maxAttempts; i++ {
|
|
||||||
err = hcsshim.CreateComputeSystem(containerID, configuration)
|
|
||||||
if err == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if herr, ok := err.(*hcsshim.HcsError); ok {
|
|
||||||
if herr.Err != syscall.ERROR_NOT_FOUND && // Element not found
|
|
||||||
herr.Err != syscall.ERROR_FILE_NOT_FOUND && // The system cannot find the file specified
|
|
||||||
herr.Err != ErrorNoNetwork && // The network is not present or not started
|
|
||||||
herr.Err != ErrorBadPathname && // The specified path is invalid
|
|
||||||
herr.Err != CoEClassstring && // Invalid class string
|
|
||||||
herr.Err != ErrorInvalidObject { // The object identifier does not represent a valid object
|
|
||||||
logrus.Debugln("Failed to create temporary container ", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
logrus.Warnf("Invoking Windows TP4 retry hack (%d of %d)", i, maxAttempts-1)
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a container object for calling start on it.
|
// Construct a container object for calling start on it.
|
||||||
|
|
|
@ -4,11 +4,7 @@ package windowsoci
|
||||||
// writing, Windows does not have a spec defined in opencontainers/specs,
|
// writing, Windows does not have a spec defined in opencontainers/specs,
|
||||||
// hence this is an interim workaround. TODO Windows: FIXME @jhowardmsft
|
// hence this is an interim workaround. TODO Windows: FIXME @jhowardmsft
|
||||||
|
|
||||||
import (
|
import "fmt"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/docker/go-connections/nat"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WindowsSpec is the full specification for Windows containers.
|
// WindowsSpec is the full specification for Windows containers.
|
||||||
type WindowsSpec struct {
|
type WindowsSpec struct {
|
||||||
|
@ -113,15 +109,6 @@ type HvRuntime struct {
|
||||||
|
|
||||||
// Networking contains the platform specific network settings for the container
|
// Networking contains the platform specific network settings for the container
|
||||||
type Networking struct {
|
type Networking struct {
|
||||||
// TODO Windows TP5. The following three fields are for 'legacy' non-
|
|
||||||
// libnetwork networking through HCS. They can be removed once TP4 is
|
|
||||||
// no longer supported. Also remove in libcontainerd\client_windows.go,
|
|
||||||
// function Create(), and in daemon\oci_windows.go, function CreateSpec()
|
|
||||||
MacAddress string `json:"mac,omitempty"`
|
|
||||||
Bridge string `json:"bridge,omitempty"`
|
|
||||||
PortBindings nat.PortMap `json:"port_bindings,omitempty"`
|
|
||||||
// End of TODO Windows TP5.
|
|
||||||
|
|
||||||
// List of endpoints to be attached to the container
|
// List of endpoints to be attached to the container
|
||||||
EndpointList []string `json:"endpoints,omitempty"`
|
EndpointList []string `json:"endpoints,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package opts
|
package opts
|
||||||
|
|
||||||
// TODO Windows. Identify bug in GOLang 1.5.1 and/or Windows Server 2016 TP4.
|
// TODO Windows. Identify bug in GOLang 1.5.1+ and/or Windows Server 2016 TP5.
|
||||||
// @jhowardmsft, @swernli.
|
// @jhowardmsft, @swernli.
|
||||||
//
|
//
|
||||||
// On Windows, this mitigates a problem with the default options of running
|
// On Windows, this mitigates a problem with the default options of running
|
||||||
// a docker client against a local docker daemon on TP4.
|
// a docker client against a local docker daemon on TP5.
|
||||||
//
|
//
|
||||||
// What was found that if the default host is "localhost", even if the client
|
// What was found that if the default host is "localhost", even if the client
|
||||||
// (and daemon as this is local) is not physically on a network, and the DNS
|
// (and daemon as this is local) is not physically on a network, and the DNS
|
||||||
|
@ -35,7 +35,7 @@ package opts
|
||||||
// time="2015-11-06T13:38:38.326882500-08:00" level=info msg="POST /v1.22/containers/984758282b842f779e805664b2c95d563adc9a979c8a3973e68c807843ee4757/attach?stderr=1&stdin=1&stdout=1&stream=1"
|
// time="2015-11-06T13:38:38.326882500-08:00" level=info msg="POST /v1.22/containers/984758282b842f779e805664b2c95d563adc9a979c8a3973e68c807843ee4757/attach?stderr=1&stdin=1&stdout=1&stream=1"
|
||||||
//
|
//
|
||||||
// We suspect this is either a bug introduced in GOLang 1.5.1, or that a change
|
// We suspect this is either a bug introduced in GOLang 1.5.1, or that a change
|
||||||
// in GOLang 1.5.1 (from 1.4.3) is exposing a bug in Windows TP4. In theory,
|
// in GOLang 1.5.1 (from 1.4.3) is exposing a bug in Windows. In theory,
|
||||||
// the Windows networking stack is supposed to resolve "localhost" internally,
|
// the Windows networking stack is supposed to resolve "localhost" internally,
|
||||||
// without hitting DNS, or even reading the hosts file (which is why localhost
|
// without hitting DNS, or even reading the hosts file (which is why localhost
|
||||||
// is commented out in the hosts file on Windows).
|
// is commented out in the hosts file on Windows).
|
||||||
|
@ -44,12 +44,12 @@ package opts
|
||||||
// address does not cause the delay.
|
// address does not cause the delay.
|
||||||
//
|
//
|
||||||
// This does not occur with the docker client built with 1.4.3 on the same
|
// This does not occur with the docker client built with 1.4.3 on the same
|
||||||
// Windows TP4 build, regardless of whether the daemon is built using 1.5.1
|
// Windows build, regardless of whether the daemon is built using 1.5.1
|
||||||
// or 1.4.3. It does not occur on Linux. We also verified we see the same thing
|
// or 1.4.3. It does not occur on Linux. We also verified we see the same thing
|
||||||
// on a cross-compiled Windows binary (from Linux).
|
// on a cross-compiled Windows binary (from Linux).
|
||||||
//
|
//
|
||||||
// Final note: This is a mitigation, not a 'real' fix. It is still susceptible
|
// Final note: This is a mitigation, not a 'real' fix. It is still susceptible
|
||||||
// to the delay in TP4 if a user were to do 'docker run -H=tcp://localhost:2375...'
|
// to the delay if a user were to do 'docker run -H=tcp://localhost:2375...'
|
||||||
// explicitly.
|
// explicitly.
|
||||||
|
|
||||||
// DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080
|
// DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080
|
||||||
|
|
|
@ -64,11 +64,6 @@ func useNativeConsole() bool {
|
||||||
return false
|
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the console modes. If this fails, we can't use the native console
|
// Get the console modes. If this fails, we can't use the native console
|
||||||
state, err := getNativeConsole()
|
state, err := getNativeConsole()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue