Signed-off-by: Darren Stahl <darst@microsoft.com>
| ... | ... |
@@ -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 |
|