Browse code

Windows: Remove TP4 support from main code

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2016/04/07 04:01:29
Showing 11 changed files
... ...
@@ -1,24 +1,11 @@
1
-// +build windows
2
-
3 1
 package dockerfile
4 2
 
5
-import (
6
-	"fmt"
7
-
8
-	"github.com/Microsoft/hcsshim"
9
-)
3
+import "fmt"
10 4
 
11
-// platformSupports is a short-term function to give users a quality error
12
-// message if a Dockerfile uses a command not supported on the platform.
5
+// platformSupports is gives users a quality error message if a Dockerfile uses
6
+// a command not supported on the platform.
13 7
 func platformSupports(command string) error {
14 8
 	switch command {
15
-	// TODO Windows TP5. Expose can be removed from here once TP4 is
16
-	// no longer supported.
17
-	case "expose":
18
-		if !hcsshim.IsTP4() {
19
-			break
20
-		}
21
-		fallthrough
22 9
 	case "user", "stopsignal", "arg":
23 10
 		return fmt.Errorf("The daemon on this platform does not support the command '%s'", command)
24 11
 	}
... ...
@@ -7,7 +7,7 @@ import "github.com/docker/docker/container"
7 7
 // cannot be configured with a read-only rootfs.
8 8
 //
9 9
 // This is a no-op on Windows which does not support read-only volumes, or
10
-// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP4
10
+// extracting to a mount point inside a volume. TODO Windows: FIXME Post-TP5
11 11
 func checkIfPathIsInAVolume(container *container.Container, absPath string) (bool, error) {
12 12
 	return false, nil
13 13
 }
... ...
@@ -322,13 +322,6 @@ func (daemon *Daemon) updateContainerNetworkSettings(container *container.Contai
322 322
 		err error
323 323
 	)
324 324
 
325
-	// TODO Windows: Remove this once TP4 builds are not supported
326
-	// Windows TP4 build don't support libnetwork and in that case
327
-	// daemon.netController will be nil
328
-	if daemon.netController == nil {
329
-		return nil
330
-	}
331
-
332 325
 	mode := container.HostConfig.NetworkMode
333 326
 	if container.Config.NetworkDisabled || mode.IsContainer() {
334 327
 		return nil
... ...
@@ -511,13 +504,6 @@ func (daemon *Daemon) updateNetworkConfig(container *container.Container, idOrNa
511 511
 }
512 512
 
513 513
 func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) {
514
-	// TODO Windows: Remove this once TP4 builds are not supported
515
-	// Windows TP4 build don't support libnetwork and in that case
516
-	// daemon.netController will be nil
517
-	if daemon.netController == nil {
518
-		return nil
519
-	}
520
-
521 514
 	n, err := daemon.updateNetworkConfig(container, idOrName, endpointConfig, updateSettings)
522 515
 	if err != nil {
523 516
 		return err
... ...
@@ -644,13 +630,6 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network,
644 644
 func (daemon *Daemon) initializeNetworking(container *container.Container) error {
645 645
 	var err error
646 646
 
647
-	// TODO Windows: Remove this once TP4 builds are not supported
648
-	// Windows TP4 build don't support libnetwork and in that case
649
-	// daemon.netController will be nil
650
-	if daemon.netController == nil {
651
-		return nil
652
-	}
653
-
654 647
 	if container.HostConfig.NetworkMode.IsContainer() {
655 648
 		// we need to get the hosts files from the container to join
656 649
 		nc, err := daemon.getNetworkedContainer(container.ID, container.HostConfig.NetworkMode.ConnectedContainer())
... ...
@@ -39,7 +39,7 @@ func (daemon *Daemon) setupIpcDirs(container *container.Container) error {
39 39
 	return nil
40 40
 }
41 41
 
42
-// TODO Windows: Fix Post-TP4. This is a hack to allow docker cp to work
42
+// TODO Windows: Fix Post-TP5. This is a hack to allow docker cp to work
43 43
 // against containers which have volumes. You will still be able to cp
44 44
 // to somewhere on the container drive, but not to any mounted volumes
45 45
 // inside the container. Without this fix, docker cp is broken to any
... ...
@@ -46,7 +46,7 @@ func (daemon *Daemon) createContainerPlatformSpecificSettings(container *contain
46 46
 		// is deferred for now. A case where this would be useful is when
47 47
 		// a dockerfile includes a VOLUME statement, but something is created
48 48
 		// in that directory during the dockerfile processing. What this means
49
-		// on Windows for TP4 is that in that scenario, the contents will not
49
+		// on Windows for TP5 is that in that scenario, the contents will not
50 50
 		// copied, but that's (somewhat) OK as HCS will bomb out soon after
51 51
 		// at it doesn't support mapped directories which have contents in the
52 52
 		// destination path anyway.
... ...
@@ -506,34 +506,6 @@ func writeTarFromLayer(r hcsshim.LayerReader, w io.Writer) error {
506 506
 
507 507
 // exportLayer generates an archive from a layer based on the given ID.
508 508
 func (d *Driver) exportLayer(id string, parentLayerPaths []string) (archive.Archive, error) {
509
-	if hcsshim.IsTP4() {
510
-		// Export in TP4 format to maintain compatibility with existing images and
511
-		// because ExportLayer is somewhat broken on TP4 and can't work with the new
512
-		// scheme.
513
-		tempFolder, err := ioutil.TempDir("", "hcs")
514
-		if err != nil {
515
-			return nil, err
516
-		}
517
-		defer func() {
518
-			if err != nil {
519
-				os.RemoveAll(tempFolder)
520
-			}
521
-		}()
522
-
523
-		if err = hcsshim.ExportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
524
-			return nil, err
525
-		}
526
-		archive, err := archive.Tar(tempFolder, archive.Uncompressed)
527
-		if err != nil {
528
-			return nil, err
529
-		}
530
-		return ioutils.NewReadCloserWrapper(archive, func() error {
531
-			err := archive.Close()
532
-			os.RemoveAll(tempFolder)
533
-			return err
534
-		}), nil
535
-	}
536
-
537 509
 	var r hcsshim.LayerReader
538 510
 	r, err := hcsshim.NewLayerReader(d.info, id, parentLayerPaths)
539 511
 	if err != nil {
... ...
@@ -598,24 +570,6 @@ func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter) (int64, error) {
598 598
 
599 599
 // importLayer adds a new layer to the tag and graph store based on the given data.
600 600
 func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPaths []string) (size int64, err error) {
601
-	if hcsshim.IsTP4() {
602
-		// Import from TP4 format to maintain compatibility with existing images.
603
-		var tempFolder string
604
-		tempFolder, err = ioutil.TempDir("", "hcs")
605
-		if err != nil {
606
-			return
607
-		}
608
-		defer os.RemoveAll(tempFolder)
609
-
610
-		if size, err = chrootarchive.ApplyLayer(tempFolder, layerData); err != nil {
611
-			return
612
-		}
613
-		if err = hcsshim.ImportLayer(d.info, id, tempFolder, parentLayerPaths); err != nil {
614
-			return
615
-		}
616
-		return
617
-	}
618
-
619 601
 	var w hcsshim.LayerWriter
620 602
 	w, err = hcsshim.NewLayerWriter(d.info, id, parentLayerPaths)
621 603
 	if err != nil {
... ...
@@ -736,31 +690,5 @@ func (d *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
736 736
 		return nil, err
737 737
 	}
738 738
 
739
-	if hcsshim.IsTP4() {
740
-		// The export format for TP4 is different from the contents of the layer, so
741
-		// fall back to exporting the layer and getting file contents from there.
742
-		layerChain, err := d.getLayerChain(id)
743
-		if err != nil {
744
-			return nil, err
745
-		}
746
-
747
-		var tempFolder string
748
-		tempFolder, err = ioutil.TempDir("", "hcs")
749
-		if err != nil {
750
-			return nil, err
751
-		}
752
-		defer func() {
753
-			if err != nil {
754
-				os.RemoveAll(tempFolder)
755
-			}
756
-		}()
757
-
758
-		if err = hcsshim.ExportLayer(d.info, id, tempFolder, layerChain); err != nil {
759
-			return nil, err
760
-		}
761
-
762
-		return &fileGetDestroyCloser{storage.NewPathFileGetter(tempFolder), tempFolder}, nil
763
-	}
764
-
765 739
 	return &fileGetCloserWithBackupPrivileges{d.dir(id)}, nil
766 740
 }
... ...
@@ -2,7 +2,6 @@ package daemon
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"strings"
6 5
 	"syscall"
7 6
 
8 7
 	"github.com/docker/docker/container"
... ...
@@ -103,7 +102,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
103 103
 	}
104 104
 	s.Windows.LayerPaths = layerPaths
105 105
 
106
-	// In s.Windows.Networking (TP5+ libnetwork way of doing things)
106
+	// In s.Windows.Networking
107 107
 	// Connect all the libnetwork allocated networks to the container
108 108
 	var epList []string
109 109
 	if c.NetworkSettings != nil {
... ...
@@ -131,26 +130,6 @@ func (daemon *Daemon) createSpec(c *container.Container) (*libcontainerd.Spec, e
131 131
 		EndpointList: epList,
132 132
 	}
133 133
 
134
-	// In s.Windows.Networking (TP4 back compat)
135
-	// TODO Windows: Post TP4 - Remove this along with definitions from spec
136
-	// and changes to libcontainerd to not read these fields.
137
-	if daemon.netController == nil {
138
-		parts := strings.SplitN(string(c.HostConfig.NetworkMode), ":", 2)
139
-		switch parts[0] {
140
-		case "none":
141
-		case "default", "": // empty string to support existing containers
142
-			if !c.Config.NetworkDisabled {
143
-				s.Windows.Networking = &windowsoci.Networking{
144
-					MacAddress:   c.Config.MacAddress,
145
-					Bridge:       daemon.configStore.bridgeConfig.Iface,
146
-					PortBindings: c.HostConfig.PortBindings,
147
-				}
148
-			}
149
-		default:
150
-			return nil, fmt.Errorf("invalid network mode: %s", c.HostConfig.NetworkMode)
151
-		}
152
-	}
153
-
154 134
 	// In s.Windows.Resources
155 135
 	// @darrenstahlmsft implement these resources
156 136
 	cpuShares := uint64(c.HostConfig.CPUShares)
... ...
@@ -6,11 +6,8 @@ import (
6 6
 	"fmt"
7 7
 	"io"
8 8
 	"path/filepath"
9
-	"strconv"
10 9
 	"strings"
11
-
12 10
 	"syscall"
13
-	"time"
14 11
 
15 12
 	"github.com/Microsoft/hcsshim"
16 13
 	"github.com/Sirupsen/logrus"
... ...
@@ -22,10 +19,6 @@ type client struct {
22 22
 	// Platform specific properties below here (none presently on Windows)
23 23
 }
24 24
 
25
-// defaultContainerNAT is the default name of the container NAT device that is
26
-// preconfigured on the server. TODO Windows - Remove for TP5 support as not needed.
27
-const defaultContainerNAT = "ContainerNAT"
28
-
29 25
 // Win32 error codes that are used for various workarounds
30 26
 // These really should be ALL_CAPS to match golangs syscall library and standard
31 27
 // Win32 error conventions, but golint insists on CamelCase.
... ...
@@ -190,108 +183,15 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio
190 190
 	}
191 191
 	cu.MappedDirectories = mds
192 192
 
193
-	// TODO Windows: vv START OF TP4 BLOCK OF CODE. REMOVE ONCE TP4 IS NO LONGER SUPPORTED
194
-	if hcsshim.IsTP4() &&
195
-		spec.Windows.Networking != nil &&
196
-		spec.Windows.Networking.Bridge != "" {
197
-		// Enumerate through the port bindings specified by the user and convert
198
-		// them into the internal structure matching the JSON blob that can be
199
-		// understood by the HCS.
200
-		var pbs []portBinding
201
-		for i, v := range spec.Windows.Networking.PortBindings {
202
-			proto := strings.ToUpper(i.Proto())
203
-			if proto != "TCP" && proto != "UDP" {
204
-				return fmt.Errorf("invalid protocol %s", i.Proto())
205
-			}
206
-
207
-			if len(v) > 1 {
208
-				return fmt.Errorf("Windows does not support more than one host port in NAT settings")
209
-			}
210
-
211
-			for _, v2 := range v {
212
-				var (
213
-					iPort, ePort int
214
-					err          error
215
-				)
216
-				if len(v2.HostIP) != 0 {
217
-					return fmt.Errorf("Windows does not support host IP addresses in NAT settings")
218
-				}
219
-				if ePort, err = strconv.Atoi(v2.HostPort); err != nil {
220
-					return fmt.Errorf("invalid container port %s: %s", v2.HostPort, err)
221
-				}
222
-				if iPort, err = strconv.Atoi(i.Port()); err != nil {
223
-					return fmt.Errorf("invalid internal port %s: %s", i.Port(), err)
224
-				}
225
-				if iPort < 0 || iPort > 65535 || ePort < 0 || ePort > 65535 {
226
-					return fmt.Errorf("specified NAT port is not in allowed range")
227
-				}
228
-				pbs = append(pbs,
229
-					portBinding{ExternalPort: ePort,
230
-						InternalPort: iPort,
231
-						Protocol:     proto})
232
-			}
233
-		}
234
-
235
-		dev := device{
236
-			DeviceType: "Network",
237
-			Connection: &networkConnection{
238
-				NetworkName: spec.Windows.Networking.Bridge,
239
-				Nat: natSettings{
240
-					Name:         defaultContainerNAT,
241
-					PortBindings: pbs,
242
-				},
243
-			},
244
-		}
245
-
246
-		if spec.Windows.Networking.MacAddress != "" {
247
-			windowsStyleMAC := strings.Replace(
248
-				spec.Windows.Networking.MacAddress, ":", "-", -1)
249
-			dev.Settings = networkSettings{
250
-				MacAddress: windowsStyleMAC,
251
-			}
252
-		}
253
-		cu.Devices = append(cu.Devices, dev)
254
-	} else {
255
-		logrus.Debugln("No network interface")
256
-	}
257
-	// TODO Windows: ^^ END OF TP4 BLOCK OF CODE. REMOVE ONCE TP4 IS NO LONGER SUPPORTED
258
-
259 193
 	configurationb, err := json.Marshal(cu)
260 194
 	if err != nil {
261 195
 		return err
262 196
 	}
263 197
 
198
+	// Create the compute system
264 199
 	configuration := string(configurationb)
265
-
266
-	// TODO Windows TP5 timeframe. Remove when TP4 is no longer supported.
267
-	// The following a workaround for Windows TP4 which has a networking
268
-	// bug which fairly frequently returns an error. Back off and retry.
269
-	if !hcsshim.IsTP4() {
270
-		if err := hcsshim.CreateComputeSystem(containerID, configuration); err != nil {
271
-			return err
272
-		}
273
-	} else {
274
-		maxAttempts := 5
275
-		for i := 1; i <= maxAttempts; i++ {
276
-			err = hcsshim.CreateComputeSystem(containerID, configuration)
277
-			if err == nil {
278
-				break
279
-			}
280
-
281
-			if herr, ok := err.(*hcsshim.HcsError); ok {
282
-				if herr.Err != syscall.ERROR_NOT_FOUND && // Element not found
283
-					herr.Err != syscall.ERROR_FILE_NOT_FOUND && // The system cannot find the file specified
284
-					herr.Err != ErrorNoNetwork && // The network is not present or not started
285
-					herr.Err != ErrorBadPathname && // The specified path is invalid
286
-					herr.Err != CoEClassstring && // Invalid class string
287
-					herr.Err != ErrorInvalidObject { // The object identifier does not represent a valid object
288
-					logrus.Debugln("Failed to create temporary container ", err)
289
-					return err
290
-				}
291
-				logrus.Warnf("Invoking Windows TP4 retry hack (%d of %d)", i, maxAttempts-1)
292
-				time.Sleep(50 * time.Millisecond)
293
-			}
294
-		}
200
+	if err := hcsshim.CreateComputeSystem(containerID, configuration); err != nil {
201
+		return err
295 202
 	}
296 203
 
297 204
 	// Construct a container object for calling start on it.
... ...
@@ -4,11 +4,7 @@ package windowsoci
4 4
 // writing, Windows does not have a spec defined in opencontainers/specs,
5 5
 // hence this is an interim workaround. TODO Windows: FIXME @jhowardmsft
6 6
 
7
-import (
8
-	"fmt"
9
-
10
-	"github.com/docker/go-connections/nat"
11
-)
7
+import "fmt"
12 8
 
13 9
 // WindowsSpec is the full specification for Windows containers.
14 10
 type WindowsSpec struct {
... ...
@@ -113,15 +109,6 @@ type HvRuntime struct {
113 113
 
114 114
 // Networking contains the platform specific network settings for the container
115 115
 type Networking struct {
116
-	// TODO Windows TP5. The following three fields are for 'legacy' non-
117
-	// libnetwork networking through HCS. They can be removed once TP4 is
118
-	// no longer supported. Also remove in libcontainerd\client_windows.go,
119
-	// function Create(), and in daemon\oci_windows.go, function CreateSpec()
120
-	MacAddress   string      `json:"mac,omitempty"`
121
-	Bridge       string      `json:"bridge,omitempty"`
122
-	PortBindings nat.PortMap `json:"port_bindings,omitempty"`
123
-	// End of TODO Windows TP5.
124
-
125 116
 	// List of endpoints to be attached to the container
126 117
 	EndpointList []string `json:"endpoints,omitempty"`
127 118
 }
... ...
@@ -1,10 +1,10 @@
1 1
 package opts
2 2
 
3
-// TODO Windows. Identify bug in GOLang 1.5.1 and/or Windows Server 2016 TP4.
3
+// TODO Windows. Identify bug in GOLang 1.5.1+ and/or Windows Server 2016 TP5.
4 4
 // @jhowardmsft, @swernli.
5 5
 //
6 6
 // On Windows, this mitigates a problem with the default options of running
7
-// a docker client against a local docker daemon on TP4.
7
+// a docker client against a local docker daemon on TP5.
8 8
 //
9 9
 // What was found that if the default host is "localhost", even if the client
10 10
 // (and daemon as this is local) is not physically on a network, and the DNS
... ...
@@ -35,7 +35,7 @@ package opts
35 35
 // 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"
36 36
 //
37 37
 // We suspect this is either a bug introduced in GOLang 1.5.1, or that a change
38
-// in GOLang 1.5.1 (from 1.4.3) is exposing a bug in Windows TP4. In theory,
38
+// in GOLang 1.5.1 (from 1.4.3) is exposing a bug in Windows. In theory,
39 39
 // the Windows networking stack is supposed to resolve "localhost" internally,
40 40
 // without hitting DNS, or even reading the hosts file (which is why localhost
41 41
 // is commented out in the hosts file on Windows).
... ...
@@ -44,12 +44,12 @@ package opts
44 44
 // address does not cause the delay.
45 45
 //
46 46
 // This does not occur with the docker client built with 1.4.3 on the same
47
-// Windows TP4 build, regardless of whether the daemon is built using 1.5.1
47
+// Windows build, regardless of whether the daemon is built using 1.5.1
48 48
 // or 1.4.3. It does not occur on Linux. We also verified we see the same thing
49 49
 // on a cross-compiled Windows binary (from Linux).
50 50
 //
51 51
 // Final note: This is a mitigation, not a 'real' fix. It is still susceptible
52
-// to the delay in TP4 if a user were to do 'docker run -H=tcp://localhost:2375...'
52
+// to the delay if a user were to do 'docker run -H=tcp://localhost:2375...'
53 53
 // explicitly.
54 54
 
55 55
 // 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 {
64 64
 		return false
65 65
 	}
66 66
 
67
-	// Must have a late pre-release TP4 build of Windows Server 2016/Windows 10 TH2 or later
68
-	if osv.Build < 10578 {
69
-		return false
70
-	}
71
-
72 67
 	// Get the console modes. If this fails, we can't use the native console
73 68
 	state, err := getNativeConsole()
74 69
 	if err != nil {