diff --git a/builder/dockerfile/evaluator_windows.go b/builder/dockerfile/evaluator_windows.go index d79dd62980..c14498a0b5 100644 --- a/builder/dockerfile/evaluator_windows.go +++ b/builder/dockerfile/evaluator_windows.go @@ -1,24 +1,11 @@ -// +build windows - package dockerfile -import ( - "fmt" +import "fmt" - "github.com/Microsoft/hcsshim" -) - -// platformSupports is a short-term function to give users a quality error -// message if a Dockerfile uses a command not supported on the platform. +// platformSupports is gives users a quality error message if a Dockerfile uses +// a command not supported on the platform. func platformSupports(command string) error { 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": return fmt.Errorf("The daemon on this platform does not support the command '%s'", command) } diff --git a/daemon/archive_windows.go b/daemon/archive_windows.go index 4cefb8de54..b3a1045341 100644 --- a/daemon/archive_windows.go +++ b/daemon/archive_windows.go @@ -7,7 +7,7 @@ import "github.com/docker/docker/container" // cannot be configured with a read-only rootfs. // // 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) { return false, nil } diff --git a/daemon/container_operations.go b/daemon/container_operations.go index 310f9bb497..227098721f 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -322,13 +322,6 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai 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 if container.Config.NetworkDisabled || mode.IsContainer() { 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) { - // 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) if err != nil { return err @@ -644,13 +630,6 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network, func (daemon *Daemon) initializeNetworking(container *container.Container) 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() { // we need to get the hosts files from the container to join nc, err := daemon.getNetworkedContainer(container.ID, container.HostConfig.NetworkMode.ConnectedContainer()) diff --git a/daemon/container_operations_windows.go b/daemon/container_operations_windows.go index 701bfd8c90..05e41ed321 100644 --- a/daemon/container_operations_windows.go +++ b/daemon/container_operations_windows.go @@ -39,7 +39,7 @@ func (daemon *Daemon) setupIpcDirs(container *container.Container) error { 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 // to somewhere on the container drive, but not to any mounted volumes // inside the container. Without this fix, docker cp is broken to any diff --git a/daemon/create_windows.go b/daemon/create_windows.go index 6bb356ad3e..6aabddad5e 100644 --- a/daemon/create_windows.go +++ b/daemon/create_windows.go @@ -46,7 +46,7 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain // is deferred for now. A case where this would be useful is when // a dockerfile includes a VOLUME statement, but something is created // 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 // at it doesn't support mapped directories which have contents in the // destination path anyway. diff --git a/daemon/graphdriver/windows/windows.go b/daemon/graphdriver/windows/windows.go index 239df05c46..0d51d43f74 100644 --- a/daemon/graphdriver/windows/windows.go +++ b/daemon/graphdriver/windows/windows.go @@ -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. 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 r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths) 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. 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 w, err = hcsshim.NewLayerWriter(d.info, id, parentLayerPaths) if err != nil { @@ -736,31 +690,5 @@ func (d *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) { 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 } diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go index 06eb7f5b4d..7da8ec4f99 100644 --- a/daemon/oci_windows.go +++ b/daemon/oci_windows.go @@ -2,7 +2,6 @@ package daemon import ( "fmt" - "strings" "syscall" "github.com/docker/docker/container" @@ -103,7 +102,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e } 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 var epList []string if c.NetworkSettings != nil { @@ -131,26 +130,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e 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 // @darrenstahlmsft implement these resources cpuShares := uint64(c.HostConfig.CPUShares) diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index 50cb4168f7..9c3e5a6c68 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -6,11 +6,8 @@ import ( "fmt" "io" "path/filepath" - "strconv" "strings" - "syscall" - "time" "github.com/Microsoft/hcsshim" "github.com/Sirupsen/logrus" @@ -22,10 +19,6 @@ type client struct { // 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 // These really should be ALL_CAPS to match golangs syscall library and standard // 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 - // 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) if err != nil { return err } + // Create the compute system configuration := string(configurationb) - - // TODO Windows TP5 timeframe. Remove when TP4 is no longer supported. - // 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) - } - } + if err := hcsshim.CreateComputeSystem(containerID, configuration); err != nil { + return err } // Construct a container object for calling start on it. diff --git a/libcontainerd/windowsoci/oci_windows.go b/libcontainerd/windowsoci/oci_windows.go index 3b9f5a3a8a..b5eb02d5eb 100644 --- a/libcontainerd/windowsoci/oci_windows.go +++ b/libcontainerd/windowsoci/oci_windows.go @@ -4,11 +4,7 @@ package windowsoci // writing, Windows does not have a spec defined in opencontainers/specs, // hence this is an interim workaround. TODO Windows: FIXME @jhowardmsft -import ( - "fmt" - - "github.com/docker/go-connections/nat" -) +import "fmt" // WindowsSpec is the full specification for Windows containers. type WindowsSpec struct { @@ -113,15 +109,6 @@ type HvRuntime struct { // Networking contains the platform specific network settings for the container 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 EndpointList []string `json:"endpoints,omitempty"` } diff --git a/opts/opts_windows.go b/opts/opts_windows.go index 2a9e2be744..ebe40c969c 100644 --- a/opts/opts_windows.go +++ b/opts/opts_windows.go @@ -1,10 +1,10 @@ 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. // // 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 // (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" // // 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, // without hitting DNS, or even reading the hosts file (which is why localhost // is commented out in the hosts file on Windows). @@ -44,12 +44,12 @@ package opts // address does not cause the delay. // // 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 // on a cross-compiled Windows binary (from Linux). // // 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. // DefaultHTTPHost Default HTTP Host used if only port is provided to -H flag e.g. docker daemon -H tcp://:8080 diff --git a/pkg/term/term_windows.go b/pkg/term/term_windows.go index 472602a729..cd21b5fc2b 100644 --- a/pkg/term/term_windows.go +++ b/pkg/term/term_windows.go @@ -64,11 +64,6 @@ func useNativeConsole() bool { 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 state, err := getNativeConsole() if err != nil {