@@ -6,11 +6,8 @@ import (
66 "fmt"
77 "io"
88 "path/filepath"
9- "strconv"
109 "strings"
11-
1210 "syscall"
13- "time"
1411
1512 "github.com/Microsoft/hcsshim"
1613 "github.com/Sirupsen/logrus"
@@ -22,10 +19,6 @@ type client struct {
2219 // Platform specific properties below here (none presently on Windows)
2320}
2421
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-
2922// Win32 error codes that are used for various workarounds
3023// These really should be ALL_CAPS to match golangs syscall library and standard
3124// Win32 error conventions, but golint insists on CamelCase.
@@ -190,108 +183,15 @@ func (clnt *client) Create(containerID string, spec Spec, options ...CreateOptio
190183 }
191184 cu .MappedDirectories = mds
192185
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-
259186 configurationb , err := json .Marshal (cu )
260187 if err != nil {
261188 return err
262189 }
263190
191+ // Create the compute system
264192 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- }
193+ if err := hcsshim .CreateComputeSystem (containerID , configuration ); err != nil {
194+ return err
295195 }
296196
297197 // Construct a container object for calling start on it.
0 commit comments