Browse code

Update hcsshim to v0.6.7 for go1.9 support

Signed-off-by: Darren Stahl <darst@microsoft.com>

Darren Stahl authored on 2017/11/21 09:27:21
Showing 8 changed files
... ...
@@ -1,6 +1,6 @@
1 1
 # the following lines are in sorted order, FYI
2 2
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
3
-github.com/Microsoft/hcsshim v0.6.5
3
+github.com/Microsoft/hcsshim v0.6.7
4 4
 github.com/Microsoft/go-winio v0.4.5
5 5
 github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76
6 6
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
... ...
@@ -72,6 +72,22 @@ var (
72 72
 	ErrPlatformNotSupported = errors.New("unsupported platform request")
73 73
 )
74 74
 
75
+type EndpointNotFoundError struct {
76
+	EndpointName string
77
+}
78
+
79
+func (e EndpointNotFoundError) Error() string {
80
+	return fmt.Sprintf("Endpoint %s not found", e.EndpointName)
81
+}
82
+
83
+type NetworkNotFoundError struct {
84
+	NetworkName string
85
+}
86
+
87
+func (e NetworkNotFoundError) Error() string {
88
+	return fmt.Sprintf("Network %s not found", e.NetworkName)
89
+}
90
+
75 91
 // ProcessError is an error encountered in HCS during an operation on a Process object
76 92
 type ProcessError struct {
77 93
 	Process   *process
... ...
@@ -174,6 +190,12 @@ func makeProcessError(process *process, operation string, extraInfo string, err
174 174
 // will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
175 175
 func IsNotExist(err error) bool {
176 176
 	err = getInnerError(err)
177
+	if _, ok := err.(EndpointNotFoundError); ok {
178
+		return true
179
+	}
180
+	if _, ok := err.(NetworkNotFoundError); ok {
181
+		return true
182
+	}
177 183
 	return err == ErrComputeSystemDoesNotExist ||
178 184
 		err == ErrElementNotFound ||
179 185
 		err == ErrProcNotFound
... ...
@@ -2,7 +2,6 @@ package hcsshim
2 2
 
3 3
 import (
4 4
 	"encoding/json"
5
-	"fmt"
6 5
 	"net"
7 6
 
8 7
 	"github.com/sirupsen/logrus"
... ...
@@ -135,7 +134,7 @@ func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
135 135
 			return &hnsEndpoint, nil
136 136
 		}
137 137
 	}
138
-	return nil, fmt.Errorf("Endpoint %v not found", endpointName)
138
+	return nil, EndpointNotFoundError{EndpointName: endpointName}
139 139
 }
140 140
 
141 141
 // Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
... ...
@@ -192,18 +191,24 @@ func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
192 192
 	return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
193 193
 }
194 194
 
195
-// ApplyACLPolicy applies Acl Policy on the Endpoint
196
-func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {
195
+// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
196
+func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
197 197
 	operation := "ApplyACLPolicy"
198 198
 	title := "HCSShim::HNSEndpoint::" + operation
199 199
 	logrus.Debugf(title+" id=%s", endpoint.Id)
200 200
 
201
-	jsonString, err := json.Marshal(policy)
202
-	if err != nil {
203
-		return err
201
+	for _, policy := range policies {
202
+		if policy == nil {
203
+			continue
204
+		}
205
+		jsonString, err := json.Marshal(policy)
206
+		if err != nil {
207
+			return err
208
+		}
209
+		endpoint.Policies = append(endpoint.Policies, jsonString)
204 210
 	}
205
-	endpoint.Policies[0] = jsonString
206
-	_, err = endpoint.Update()
211
+
212
+	_, err := endpoint.Update()
207 213
 	return err
208 214
 }
209 215
 
... ...
@@ -2,7 +2,6 @@ package hcsshim
2 2
 
3 3
 import (
4 4
 	"encoding/json"
5
-	"fmt"
6 5
 	"net"
7 6
 
8 7
 	"github.com/sirupsen/logrus"
... ...
@@ -90,7 +89,7 @@ func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
90 90
 			return &hnsnetwork, nil
91 91
 		}
92 92
 	}
93
-	return nil, fmt.Errorf("Network %v not found", networkName)
93
+	return nil, NetworkNotFoundError{NetworkName: networkName}
94 94
 }
95 95
 
96 96
 // Create Network by sending NetworkRequest to HNS.
... ...
@@ -75,19 +75,18 @@ const (
75 75
 )
76 76
 
77 77
 type ACLPolicy struct {
78
-	Type          PolicyType `json:"Type"`
79
-	Protocol      uint16
80
-	InternalPort  uint16
81
-	Action        ActionType
82
-	Direction     DirectionType
83
-	LocalAddress  string
84
-	RemoteAddress string
85
-	LocalPort     uint16
86
-	RemotePort    uint16
87
-	RuleType      RuleType `json:"RuleType,omitempty"`
88
-
89
-	Priority    uint16
90
-	ServiceName string
78
+	Type            PolicyType `json:"Type"`
79
+	Protocol        uint16
80
+	InternalPort    uint16
81
+	Action          ActionType
82
+	Direction       DirectionType
83
+	LocalAddresses  string
84
+	RemoteAddresses string
85
+	LocalPort       uint16
86
+	RemotePort      uint16
87
+	RuleType        RuleType `json:"RuleType,omitempty"`
88
+	Priority        uint16
89
+	ServiceName     string
91 90
 }
92 91
 
93 92
 type Policy struct {
... ...
@@ -472,15 +472,21 @@ func cloneTree(srcPath, destPath string, mutatedFiles map[string]bool) error {
472 472
 		}
473 473
 		destFilePath := filepath.Join(destPath, relPath)
474 474
 
475
+		fileAttributes := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
475 476
 		// Directories, reparse points, and files that will be mutated during
476 477
 		// utility VM import must be copied. All other files can be hard linked.
477
-		isReparsePoint := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0
478
-		if info.IsDir() || isReparsePoint || mutatedFiles[relPath] {
479
-			fi, err := copyFileWithMetadata(srcFilePath, destFilePath, info.IsDir())
478
+		isReparsePoint := fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0
479
+		// In go1.9, FileInfo.IsDir() returns false if the directory is also a symlink.
480
+		// See: https://github.com/golang/go/commit/1989921aef60c83e6f9127a8448fb5ede10e9acc
481
+		// Fixes the problem by checking syscall.FILE_ATTRIBUTE_DIRECTORY directly
482
+		isDir := fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0
483
+
484
+		if isDir || isReparsePoint || mutatedFiles[relPath] {
485
+			fi, err := copyFileWithMetadata(srcFilePath, destFilePath, isDir)
480 486
 			if err != nil {
481 487
 				return err
482 488
 			}
483
-			if info.IsDir() && !isReparsePoint {
489
+			if isDir && !isReparsePoint {
484 490
 				di = append(di, dirInfo{path: destFilePath, fileInfo: *fi})
485 491
 			}
486 492
 		} else {
... ...
@@ -490,8 +496,9 @@ func cloneTree(srcPath, destPath string, mutatedFiles map[string]bool) error {
490 490
 			}
491 491
 		}
492 492
 
493
-		// Don't recurse on reparse points.
494
-		if info.IsDir() && isReparsePoint {
493
+		// Don't recurse on reparse points in go1.8 and older. Filepath.Walk
494
+		// handles this in go1.9 and newer.
495
+		if isDir && isReparsePoint && shouldSkipDirectoryReparse {
495 496
 			return filepath.SkipDir
496 497
 		}
497 498
 
498 499
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+// +build !go1.9
1
+
2
+package hcsshim
3
+
4
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
5
+// during filepath.Walk. This is fixed in go1.9
6
+var shouldSkipDirectoryReparse = true
0 7
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+// +build go1.9
1
+
2
+package hcsshim
3
+
4
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
5
+// during filepath.Walk. This is fixed in go1.9
6
+var shouldSkipDirectoryReparse = false