vndr hcsshim to 79062a5
Signed-off-by: Andrew Hsu <andrewhsu@docker.com>
diff --git a/vendor.conf b/vendor.conf
index 91cde6d..559ac51 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -1,6 +1,6 @@
# the following lines are in sorted order, FYI
github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
-github.com/Microsoft/hcsshim v0.6.8
+github.com/Microsoft/hcsshim 79062a5b985d24ef42a4252a1b63a93ec450e407
github.com/Microsoft/go-winio v0.4.6
github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
diff --git a/vendor/github.com/Microsoft/hcsshim/baselayer.go b/vendor/github.com/Microsoft/hcsshim/baselayer.go
index 9babd4e..860185c 100644
--- a/vendor/github.com/Microsoft/hcsshim/baselayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/baselayer.go
@@ -10,7 +10,7 @@
)
type baseLayerWriter struct {
- root string
+ root *os.File
f *os.File
bw *winio.BackupFileWriter
err error
@@ -26,10 +26,10 @@
// reapplyDirectoryTimes reapplies directory modification, creation, etc. times
// after processing of the directory tree has completed. The times are expected
// to be ordered such that parent directories come before child directories.
-func reapplyDirectoryTimes(dis []dirInfo) error {
+func reapplyDirectoryTimes(root *os.File, dis []dirInfo) error {
for i := range dis {
di := &dis[len(dis)-i-1] // reverse order: process child directories first
- f, err := winio.OpenForBackup(di.path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, syscall.OPEN_EXISTING)
+ f, err := openRelative(di.path, root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_OPEN, _FILE_DIRECTORY_FILE)
if err != nil {
return err
}
@@ -75,12 +75,6 @@
w.hasUtilityVM = true
}
- path := filepath.Join(w.root, name)
- path, err = makeLongAbsPath(path)
- if err != nil {
- return err
- }
-
var f *os.File
defer func() {
if f != nil {
@@ -88,27 +82,23 @@
}
}()
- createmode := uint32(syscall.CREATE_NEW)
+ extraFlags := uint32(0)
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- err := os.Mkdir(path, 0)
- if err != nil && !os.IsExist(err) {
- return err
- }
- createmode = syscall.OPEN_EXISTING
+ extraFlags |= _FILE_DIRECTORY_FILE
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
- w.dirInfo = append(w.dirInfo, dirInfo{path, *fileInfo})
+ w.dirInfo = append(w.dirInfo, dirInfo{name, *fileInfo})
}
}
mode := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | winio.WRITE_DAC | winio.WRITE_OWNER | winio.ACCESS_SYSTEM_SECURITY)
- f, err = winio.OpenForBackup(path, mode, syscall.FILE_SHARE_READ, createmode)
+ f, err = openRelative(name, w.root, mode, syscall.FILE_SHARE_READ, _FILE_CREATE, extraFlags)
if err != nil {
- return makeError(err, "Failed to OpenForBackup", path)
+ return makeError(err, "Failed to openRelative", name)
}
err = winio.SetFileBasicInfo(f, fileInfo)
if err != nil {
- return makeError(err, "Failed to SetFileBasicInfo", path)
+ return makeError(err, "Failed to SetFileBasicInfo", name)
}
w.f = f
@@ -129,17 +119,7 @@
return err
}
- linkpath, err := makeLongAbsPath(filepath.Join(w.root, name))
- if err != nil {
- return err
- }
-
- linktarget, err := makeLongAbsPath(filepath.Join(w.root, target))
- if err != nil {
- return err
- }
-
- return os.Link(linktarget, linkpath)
+ return linkRelative(target, w.root, name, w.root)
}
func (w *baseLayerWriter) Remove(name string) error {
@@ -155,6 +135,10 @@
}
func (w *baseLayerWriter) Close() error {
+ defer func() {
+ w.root.Close()
+ w.root = nil
+ }()
err := w.closeCurrentFile()
if err != nil {
return err
@@ -162,18 +146,22 @@
if w.err == nil {
// Restore the file times of all the directories, since they may have
// been modified by creating child directories.
- err = reapplyDirectoryTimes(w.dirInfo)
+ err = reapplyDirectoryTimes(w.root, w.dirInfo)
if err != nil {
return err
}
- err = ProcessBaseLayer(w.root)
+ err = ProcessBaseLayer(w.root.Name())
if err != nil {
return err
}
if w.hasUtilityVM {
- err = ProcessUtilityVMImage(filepath.Join(w.root, "UtilityVM"))
+ err := ensureNotReparsePointRelative("UtilityVM", w.root)
+ if err != nil {
+ return err
+ }
+ err = ProcessUtilityVMImage(filepath.Join(w.root.Name(), "UtilityVM"))
if err != nil {
return err
}
diff --git a/vendor/github.com/Microsoft/hcsshim/hcsshim.go b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
index 236ba1f..b659531 100644
--- a/vendor/github.com/Microsoft/hcsshim/hcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/hcsshim.go
@@ -11,7 +11,7 @@
"github.com/sirupsen/logrus"
)
-//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
+//go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go safeopen.go
//sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
//sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
index 7e516f8..90689cb 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsendpoint.go
@@ -1,323 +1,323 @@
-package hcsshim
-
-import (
- "encoding/json"
- "net"
-
- "github.com/sirupsen/logrus"
-)
-
-// HNSEndpoint represents a network endpoint in HNS
-type HNSEndpoint struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- VirtualNetwork string `json:",omitempty"`
- VirtualNetworkName string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacAddress string `json:",omitempty"`
- IPAddress net.IP `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- EnableInternalDNS bool `json:",omitempty"`
- DisableICC bool `json:",omitempty"`
- PrefixLength uint8 `json:",omitempty"`
- IsRemoteEndpoint bool `json:",omitempty"`
-}
-
-//SystemType represents the type of the system on which actions are done
-type SystemType string
-
-// SystemType const
-const (
- ContainerType SystemType = "Container"
- VirtualMachineType SystemType = "VirtualMachine"
- HostType SystemType = "Host"
-)
-
-// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
-// Supported resource types are Network and Request Types are Add/Remove
-type EndpointAttachDetachRequest struct {
- ContainerID string `json:"ContainerId,omitempty"`
- SystemType SystemType `json:"SystemType"`
- CompartmentID uint16 `json:"CompartmentId,omitempty"`
- VirtualNICName string `json:"VirtualNicName,omitempty"`
-}
-
-// EndpointResquestResponse is object to get the endpoint request response
-type EndpointResquestResponse struct {
- Success bool
- Error string
-}
-
-// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
-func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
- endpoint := &HNSEndpoint{}
- err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
- if err != nil {
- return nil, err
- }
-
- return endpoint, nil
-}
-
-// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
-func HNSListEndpointRequest() ([]HNSEndpoint, error) {
- var endpoint []HNSEndpoint
- err := hnsCall("GET", "/endpoints/", "", &endpoint)
- if err != nil {
- return nil, err
- }
-
- return endpoint, nil
-}
-
-// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
-func HotAttachEndpoint(containerID string, endpointID string) error {
- return modifyNetworkEndpoint(containerID, endpointID, Add)
-}
-
-// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
-func HotDetachEndpoint(containerID string, endpointID string) error {
- return modifyNetworkEndpoint(containerID, endpointID, Remove)
-}
-
-// ModifyContainer corresponding to the container id, by sending a request
-func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
- container, err := OpenContainer(id)
- if err != nil {
- if IsNotExist(err) {
- return ErrComputeSystemDoesNotExist
- }
- return getInnerError(err)
- }
- defer container.Close()
- err = container.Modify(request)
- if err != nil {
- if IsNotSupported(err) {
- return ErrPlatformNotSupported
- }
- return getInnerError(err)
- }
-
- return nil
-}
-
-func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
- requestMessage := &ResourceModificationRequestResponse{
- Resource: Network,
- Request: request,
- Data: endpointID,
- }
- err := modifyContainer(containerID, requestMessage)
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// GetHNSEndpointByID get the Endpoint by ID
-func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
- return HNSEndpointRequest("GET", endpointID, "")
-}
-
-// GetHNSEndpointByName gets the endpoint filtered by Name
-func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
- hnsResponse, err := HNSListEndpointRequest()
- if err != nil {
- return nil, err
- }
- for _, hnsEndpoint := range hnsResponse {
- if hnsEndpoint.Name == endpointName {
- return &hnsEndpoint, nil
- }
- }
- return nil, EndpointNotFoundError{EndpointName: endpointName}
-}
-
-// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
-func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
- operation := "Create"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- jsonString, err := json.Marshal(endpoint)
- if err != nil {
- return nil, err
- }
- return HNSEndpointRequest("POST", "", string(jsonString))
-}
-
-// Delete Endpoint by sending EndpointRequest to HNS
-func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
- operation := "Delete"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- return HNSEndpointRequest("DELETE", endpoint.Id, "")
-}
-
-// Update Endpoint
-func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
- operation := "Update"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
- jsonString, err := json.Marshal(endpoint)
- if err != nil {
- return nil, err
- }
- err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
-
- return endpoint, err
-}
-
-// ContainerHotAttach attaches an endpoint to a running container
-func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
- operation := "ContainerHotAttach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
-
- return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
-}
-
-// ContainerHotDetach detaches an endpoint from a running container
-func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
- operation := "ContainerHotDetach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
-
- return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
-}
-
-// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
-func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
- operation := "ApplyACLPolicy"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- for _, policy := range policies {
- if policy == nil {
- continue
- }
- jsonString, err := json.Marshal(policy)
- if err != nil {
- return err
- }
- endpoint.Policies = append(endpoint.Policies, jsonString)
- }
-
- _, err := endpoint.Update()
- return err
-}
-
-// ContainerAttach attaches an endpoint to container
-func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
- operation := "ContainerAttach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- requestMessage := &EndpointAttachDetachRequest{
- ContainerID: containerID,
- CompartmentID: compartmentID,
- SystemType: ContainerType,
- }
- response := &EndpointResquestResponse{}
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-}
-
-// ContainerDetach detaches an endpoint from container
-func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
- operation := "ContainerDetach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- requestMessage := &EndpointAttachDetachRequest{
- ContainerID: containerID,
- SystemType: ContainerType,
- }
- response := &EndpointResquestResponse{}
-
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
-}
-
-// HostAttach attaches a nic on the host
-func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
- operation := "HostAttach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
- requestMessage := &EndpointAttachDetachRequest{
- CompartmentID: compartmentID,
- SystemType: HostType,
- }
- response := &EndpointResquestResponse{}
-
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-
-}
-
-// HostDetach detaches a nic on the host
-func (endpoint *HNSEndpoint) HostDetach() error {
- operation := "HostDetach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
- requestMessage := &EndpointAttachDetachRequest{
- SystemType: HostType,
- }
- response := &EndpointResquestResponse{}
-
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
-}
-
-// VirtualMachineNICAttach attaches a endpoint to a virtual machine
-func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
- operation := "VirtualMachineNicAttach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
- requestMessage := &EndpointAttachDetachRequest{
- VirtualNICName: virtualMachineNICName,
- SystemType: VirtualMachineType,
- }
- response := &EndpointResquestResponse{}
-
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
-}
-
-// VirtualMachineNICDetach detaches a endpoint from a virtual machine
-func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
- operation := "VirtualMachineNicDetach"
- title := "HCSShim::HNSEndpoint::" + operation
- logrus.Debugf(title+" id=%s", endpoint.Id)
-
- requestMessage := &EndpointAttachDetachRequest{
- SystemType: VirtualMachineType,
- }
- response := &EndpointResquestResponse{}
-
- jsonString, err := json.Marshal(requestMessage)
- if err != nil {
- return err
- }
- return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
-}
+package hcsshim
+
+import (
+ "encoding/json"
+ "net"
+
+ "github.com/sirupsen/logrus"
+)
+
+// HNSEndpoint represents a network endpoint in HNS
+type HNSEndpoint struct {
+ Id string `json:"ID,omitempty"`
+ Name string `json:",omitempty"`
+ VirtualNetwork string `json:",omitempty"`
+ VirtualNetworkName string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+ MacAddress string `json:",omitempty"`
+ IPAddress net.IP `json:",omitempty"`
+ DNSSuffix string `json:",omitempty"`
+ DNSServerList string `json:",omitempty"`
+ GatewayAddress string `json:",omitempty"`
+ EnableInternalDNS bool `json:",omitempty"`
+ DisableICC bool `json:",omitempty"`
+ PrefixLength uint8 `json:",omitempty"`
+ IsRemoteEndpoint bool `json:",omitempty"`
+}
+
+//SystemType represents the type of the system on which actions are done
+type SystemType string
+
+// SystemType const
+const (
+ ContainerType SystemType = "Container"
+ VirtualMachineType SystemType = "VirtualMachine"
+ HostType SystemType = "Host"
+)
+
+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system
+// Supported resource types are Network and Request Types are Add/Remove
+type EndpointAttachDetachRequest struct {
+ ContainerID string `json:"ContainerId,omitempty"`
+ SystemType SystemType `json:"SystemType"`
+ CompartmentID uint16 `json:"CompartmentId,omitempty"`
+ VirtualNICName string `json:"VirtualNicName,omitempty"`
+}
+
+// EndpointResquestResponse is object to get the endpoint request response
+type EndpointResquestResponse struct {
+ Success bool
+ Error string
+}
+
+// HNSEndpointRequest makes a HNS call to modify/query a network endpoint
+func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
+ endpoint := &HNSEndpoint{}
+ err := hnsCall(method, "/endpoints/"+path, request, &endpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ return endpoint, nil
+}
+
+// HNSListEndpointRequest makes a HNS call to query the list of available endpoints
+func HNSListEndpointRequest() ([]HNSEndpoint, error) {
+ var endpoint []HNSEndpoint
+ err := hnsCall("GET", "/endpoints/", "", &endpoint)
+ if err != nil {
+ return nil, err
+ }
+
+ return endpoint, nil
+}
+
+// HotAttachEndpoint makes a HCS Call to attach the endpoint to the container
+func HotAttachEndpoint(containerID string, endpointID string) error {
+ return modifyNetworkEndpoint(containerID, endpointID, Add)
+}
+
+// HotDetachEndpoint makes a HCS Call to detach the endpoint from the container
+func HotDetachEndpoint(containerID string, endpointID string) error {
+ return modifyNetworkEndpoint(containerID, endpointID, Remove)
+}
+
+// ModifyContainer corresponding to the container id, by sending a request
+func modifyContainer(id string, request *ResourceModificationRequestResponse) error {
+ container, err := OpenContainer(id)
+ if err != nil {
+ if IsNotExist(err) {
+ return ErrComputeSystemDoesNotExist
+ }
+ return getInnerError(err)
+ }
+ defer container.Close()
+ err = container.Modify(request)
+ if err != nil {
+ if IsNotSupported(err) {
+ return ErrPlatformNotSupported
+ }
+ return getInnerError(err)
+ }
+
+ return nil
+}
+
+func modifyNetworkEndpoint(containerID string, endpointID string, request RequestType) error {
+ requestMessage := &ResourceModificationRequestResponse{
+ Resource: Network,
+ Request: request,
+ Data: endpointID,
+ }
+ err := modifyContainer(containerID, requestMessage)
+
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// GetHNSEndpointByID get the Endpoint by ID
+func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
+ return HNSEndpointRequest("GET", endpointID, "")
+}
+
+// GetHNSEndpointByName gets the endpoint filtered by Name
+func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
+ hnsResponse, err := HNSListEndpointRequest()
+ if err != nil {
+ return nil, err
+ }
+ for _, hnsEndpoint := range hnsResponse {
+ if hnsEndpoint.Name == endpointName {
+ return &hnsEndpoint, nil
+ }
+ }
+ return nil, EndpointNotFoundError{EndpointName: endpointName}
+}
+
+// Create Endpoint by sending EndpointRequest to HNS. TODO: Create a separate HNS interface to place all these methods
+func (endpoint *HNSEndpoint) Create() (*HNSEndpoint, error) {
+ operation := "Create"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ jsonString, err := json.Marshal(endpoint)
+ if err != nil {
+ return nil, err
+ }
+ return HNSEndpointRequest("POST", "", string(jsonString))
+}
+
+// Delete Endpoint by sending EndpointRequest to HNS
+func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
+ operation := "Delete"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ return HNSEndpointRequest("DELETE", endpoint.Id, "")
+}
+
+// Update Endpoint
+func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
+ operation := "Update"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ jsonString, err := json.Marshal(endpoint)
+ if err != nil {
+ return nil, err
+ }
+ err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
+
+ return endpoint, err
+}
+
+// ContainerHotAttach attaches an endpoint to a running container
+func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
+ operation := "ContainerHotAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+ return modifyNetworkEndpoint(containerID, endpoint.Id, Add)
+}
+
+// ContainerHotDetach detaches an endpoint from a running container
+func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
+ operation := "ContainerHotDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID)
+
+ return modifyNetworkEndpoint(containerID, endpoint.Id, Remove)
+}
+
+// ApplyACLPolicy applies a set of ACL Policies on the Endpoint
+func (endpoint *HNSEndpoint) ApplyACLPolicy(policies ...*ACLPolicy) error {
+ operation := "ApplyACLPolicy"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ for _, policy := range policies {
+ if policy == nil {
+ continue
+ }
+ jsonString, err := json.Marshal(policy)
+ if err != nil {
+ return err
+ }
+ endpoint.Policies = append(endpoint.Policies, jsonString)
+ }
+
+ _, err := endpoint.Update()
+ return err
+}
+
+// ContainerAttach attaches an endpoint to container
+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
+ operation := "ContainerAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ ContainerID: containerID,
+ CompartmentID: compartmentID,
+ SystemType: ContainerType,
+ }
+ response := &EndpointResquestResponse{}
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// ContainerDetach detaches an endpoint from container
+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
+ operation := "ContainerDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ ContainerID: containerID,
+ SystemType: ContainerType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// HostAttach attaches a nic on the host
+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
+ operation := "HostAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ CompartmentID: compartmentID,
+ SystemType: HostType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+
+}
+
+// HostDetach detaches a nic on the host
+func (endpoint *HNSEndpoint) HostDetach() error {
+ operation := "HostDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ SystemType: HostType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
+
+// VirtualMachineNICAttach attaches a endpoint to a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
+ operation := "VirtualMachineNicAttach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+ requestMessage := &EndpointAttachDetachRequest{
+ VirtualNICName: virtualMachineNICName,
+ SystemType: VirtualMachineType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
+}
+
+// VirtualMachineNICDetach detaches a endpoint from a virtual machine
+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
+ operation := "VirtualMachineNicDetach"
+ title := "HCSShim::HNSEndpoint::" + operation
+ logrus.Debugf(title+" id=%s", endpoint.Id)
+
+ requestMessage := &EndpointAttachDetachRequest{
+ SystemType: VirtualMachineType,
+ }
+ response := &EndpointResquestResponse{}
+
+ jsonString, err := json.Marshal(requestMessage)
+ if err != nil {
+ return err
+ }
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
index 04c1b59..398583a 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnsnetwork.go
@@ -1,141 +1,141 @@
-package hcsshim
-
-import (
- "encoding/json"
- "net"
-
- "github.com/sirupsen/logrus"
-)
-
-// Subnet is assoicated with a network and represents a list
-// of subnets available to the network
-type Subnet struct {
- AddressPrefix string `json:",omitempty"`
- GatewayAddress string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
-}
-
-// MacPool is assoicated with a network and represents a list
-// of macaddresses available to the network
-type MacPool struct {
- StartMacAddress string `json:",omitempty"`
- EndMacAddress string `json:",omitempty"`
-}
-
-// HNSNetwork represents a network in HNS
-type HNSNetwork struct {
- Id string `json:"ID,omitempty"`
- Name string `json:",omitempty"`
- Type string `json:",omitempty"`
- NetworkAdapterName string `json:",omitempty"`
- SourceMac string `json:",omitempty"`
- Policies []json.RawMessage `json:",omitempty"`
- MacPools []MacPool `json:",omitempty"`
- Subnets []Subnet `json:",omitempty"`
- DNSSuffix string `json:",omitempty"`
- DNSServerList string `json:",omitempty"`
- DNSServerCompartment uint32 `json:",omitempty"`
- ManagementIP string `json:",omitempty"`
- AutomaticDNS bool `json:",omitempty"`
-}
-
-type hnsNetworkResponse struct {
- Success bool
- Error string
- Output HNSNetwork
-}
-
-type hnsResponse struct {
- Success bool
- Error string
- Output json.RawMessage
-}
-
-// HNSNetworkRequest makes a call into HNS to update/query a single network
-func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
- var network HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
-
- return &network, nil
-}
-
-// HNSListNetworkRequest makes a HNS call to query the list of available networks
-func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
- var network []HNSNetwork
- err := hnsCall(method, "/networks/"+path, request, &network)
- if err != nil {
- return nil, err
- }
-
- return network, nil
-}
-
-// GetHNSNetworkByID
-func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
- return HNSNetworkRequest("GET", networkID, "")
-}
-
-// GetHNSNetworkName filtered by Name
-func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
- hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
- if err != nil {
- return nil, err
- }
- for _, hnsnetwork := range hsnnetworks {
- if hnsnetwork.Name == networkName {
- return &hnsnetwork, nil
- }
- }
- return nil, NetworkNotFoundError{NetworkName: networkName}
-}
-
-// Create Network by sending NetworkRequest to HNS.
-func (network *HNSNetwork) Create() (*HNSNetwork, error) {
- operation := "Create"
- title := "HCSShim::HNSNetwork::" + operation
- logrus.Debugf(title+" id=%s", network.Id)
-
- jsonString, err := json.Marshal(network)
- if err != nil {
- return nil, err
- }
- return HNSNetworkRequest("POST", "", string(jsonString))
-}
-
-// Delete Network by sending NetworkRequest to HNS
-func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
- operation := "Delete"
- title := "HCSShim::HNSNetwork::" + operation
- logrus.Debugf(title+" id=%s", network.Id)
-
- return HNSNetworkRequest("DELETE", network.Id, "")
-}
-
-// Creates an endpoint on the Network.
-func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
- return &HNSEndpoint{
- VirtualNetwork: network.Id,
- IPAddress: ipAddress,
- MacAddress: string(macAddress),
- }
-}
-
-func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
- operation := "CreateEndpoint"
- title := "HCSShim::HNSNetwork::" + operation
- logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
-
- endpoint.VirtualNetwork = network.Id
- return endpoint.Create()
-}
-
-func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
- operation := "CreateRemoteEndpoint"
- title := "HCSShim::HNSNetwork::" + operation
- logrus.Debugf(title+" id=%s", network.Id)
- endpoint.IsRemoteEndpoint = true
- return network.CreateEndpoint(endpoint)
-}
+package hcsshim
+
+import (
+ "encoding/json"
+ "net"
+
+ "github.com/sirupsen/logrus"
+)
+
+// Subnet is assoicated with a network and represents a list
+// of subnets available to the network
+type Subnet struct {
+ AddressPrefix string `json:",omitempty"`
+ GatewayAddress string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+}
+
+// MacPool is assoicated with a network and represents a list
+// of macaddresses available to the network
+type MacPool struct {
+ StartMacAddress string `json:",omitempty"`
+ EndMacAddress string `json:",omitempty"`
+}
+
+// HNSNetwork represents a network in HNS
+type HNSNetwork struct {
+ Id string `json:"ID,omitempty"`
+ Name string `json:",omitempty"`
+ Type string `json:",omitempty"`
+ NetworkAdapterName string `json:",omitempty"`
+ SourceMac string `json:",omitempty"`
+ Policies []json.RawMessage `json:",omitempty"`
+ MacPools []MacPool `json:",omitempty"`
+ Subnets []Subnet `json:",omitempty"`
+ DNSSuffix string `json:",omitempty"`
+ DNSServerList string `json:",omitempty"`
+ DNSServerCompartment uint32 `json:",omitempty"`
+ ManagementIP string `json:",omitempty"`
+ AutomaticDNS bool `json:",omitempty"`
+}
+
+type hnsNetworkResponse struct {
+ Success bool
+ Error string
+ Output HNSNetwork
+}
+
+type hnsResponse struct {
+ Success bool
+ Error string
+ Output json.RawMessage
+}
+
+// HNSNetworkRequest makes a call into HNS to update/query a single network
+func HNSNetworkRequest(method, path, request string) (*HNSNetwork, error) {
+ var network HNSNetwork
+ err := hnsCall(method, "/networks/"+path, request, &network)
+ if err != nil {
+ return nil, err
+ }
+
+ return &network, nil
+}
+
+// HNSListNetworkRequest makes a HNS call to query the list of available networks
+func HNSListNetworkRequest(method, path, request string) ([]HNSNetwork, error) {
+ var network []HNSNetwork
+ err := hnsCall(method, "/networks/"+path, request, &network)
+ if err != nil {
+ return nil, err
+ }
+
+ return network, nil
+}
+
+// GetHNSNetworkByID
+func GetHNSNetworkByID(networkID string) (*HNSNetwork, error) {
+ return HNSNetworkRequest("GET", networkID, "")
+}
+
+// GetHNSNetworkName filtered by Name
+func GetHNSNetworkByName(networkName string) (*HNSNetwork, error) {
+ hsnnetworks, err := HNSListNetworkRequest("GET", "", "")
+ if err != nil {
+ return nil, err
+ }
+ for _, hnsnetwork := range hsnnetworks {
+ if hnsnetwork.Name == networkName {
+ return &hnsnetwork, nil
+ }
+ }
+ return nil, NetworkNotFoundError{NetworkName: networkName}
+}
+
+// Create Network by sending NetworkRequest to HNS.
+func (network *HNSNetwork) Create() (*HNSNetwork, error) {
+ operation := "Create"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+
+ jsonString, err := json.Marshal(network)
+ if err != nil {
+ return nil, err
+ }
+ return HNSNetworkRequest("POST", "", string(jsonString))
+}
+
+// Delete Network by sending NetworkRequest to HNS
+func (network *HNSNetwork) Delete() (*HNSNetwork, error) {
+ operation := "Delete"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+
+ return HNSNetworkRequest("DELETE", network.Id, "")
+}
+
+// Creates an endpoint on the Network.
+func (network *HNSNetwork) NewEndpoint(ipAddress net.IP, macAddress net.HardwareAddr) *HNSEndpoint {
+ return &HNSEndpoint{
+ VirtualNetwork: network.Id,
+ IPAddress: ipAddress,
+ MacAddress: string(macAddress),
+ }
+}
+
+func (network *HNSNetwork) CreateEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+ operation := "CreateEndpoint"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s, endpointId=%s", network.Id, endpoint.Id)
+
+ endpoint.VirtualNetwork = network.Id
+ return endpoint.Create()
+}
+
+func (network *HNSNetwork) CreateRemoteEndpoint(endpoint *HNSEndpoint) (*HNSEndpoint, error) {
+ operation := "CreateRemoteEndpoint"
+ title := "HCSShim::HNSNetwork::" + operation
+ logrus.Debugf(title+" id=%s", network.Id)
+ endpoint.IsRemoteEndpoint = true
+ return network.CreateEndpoint(endpoint)
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
index 65b8e93..bf860e9 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicy.go
@@ -1,94 +1,94 @@
-package hcsshim
-
-// Type of Request Support in ModifySystem
-type PolicyType string
-
-// RequestType const
-const (
- Nat PolicyType = "NAT"
- ACL PolicyType = "ACL"
- PA PolicyType = "PA"
- VLAN PolicyType = "VLAN"
- VSID PolicyType = "VSID"
- VNet PolicyType = "VNET"
- L2Driver PolicyType = "L2Driver"
- Isolation PolicyType = "Isolation"
- QOS PolicyType = "QOS"
- OutboundNat PolicyType = "OutBoundNAT"
- ExternalLoadBalancer PolicyType = "ELB"
- Route PolicyType = "ROUTE"
-)
-
-type NatPolicy struct {
- Type PolicyType `json:"Type"`
- Protocol string
- InternalPort uint16
- ExternalPort uint16
-}
-
-type QosPolicy struct {
- Type PolicyType `json:"Type"`
- MaximumOutgoingBandwidthInBytes uint64
-}
-
-type IsolationPolicy struct {
- Type PolicyType `json:"Type"`
- VLAN uint
- VSID uint
- InDefaultIsolation bool
-}
-
-type VlanPolicy struct {
- Type PolicyType `json:"Type"`
- VLAN uint
-}
-
-type VsidPolicy struct {
- Type PolicyType `json:"Type"`
- VSID uint
-}
-
-type PaPolicy struct {
- Type PolicyType `json:"Type"`
- PA string `json:"PA"`
-}
-
-type OutboundNatPolicy struct {
- Policy
- VIP string `json:"VIP,omitempty"`
- Exceptions []string `json:"ExceptionList,omitempty"`
-}
-
-type ActionType string
-type DirectionType string
-type RuleType string
-
-const (
- Allow ActionType = "Allow"
- Block ActionType = "Block"
-
- In DirectionType = "In"
- Out DirectionType = "Out"
-
- Host RuleType = "Host"
- Switch RuleType = "Switch"
-)
-
-type ACLPolicy struct {
- Type PolicyType `json:"Type"`
- Protocol uint16
- InternalPort uint16
- Action ActionType
- Direction DirectionType
- LocalAddresses string
- RemoteAddresses string
- LocalPort uint16
- RemotePort uint16
- RuleType RuleType `json:"RuleType,omitempty"`
- Priority uint16
- ServiceName string
-}
-
-type Policy struct {
- Type PolicyType `json:"Type"`
-}
+package hcsshim
+
+// Type of Request Support in ModifySystem
+type PolicyType string
+
+// RequestType const
+const (
+ Nat PolicyType = "NAT"
+ ACL PolicyType = "ACL"
+ PA PolicyType = "PA"
+ VLAN PolicyType = "VLAN"
+ VSID PolicyType = "VSID"
+ VNet PolicyType = "VNET"
+ L2Driver PolicyType = "L2Driver"
+ Isolation PolicyType = "Isolation"
+ QOS PolicyType = "QOS"
+ OutboundNat PolicyType = "OutBoundNAT"
+ ExternalLoadBalancer PolicyType = "ELB"
+ Route PolicyType = "ROUTE"
+)
+
+type NatPolicy struct {
+ Type PolicyType `json:"Type"`
+ Protocol string
+ InternalPort uint16
+ ExternalPort uint16
+}
+
+type QosPolicy struct {
+ Type PolicyType `json:"Type"`
+ MaximumOutgoingBandwidthInBytes uint64
+}
+
+type IsolationPolicy struct {
+ Type PolicyType `json:"Type"`
+ VLAN uint
+ VSID uint
+ InDefaultIsolation bool
+}
+
+type VlanPolicy struct {
+ Type PolicyType `json:"Type"`
+ VLAN uint
+}
+
+type VsidPolicy struct {
+ Type PolicyType `json:"Type"`
+ VSID uint
+}
+
+type PaPolicy struct {
+ Type PolicyType `json:"Type"`
+ PA string `json:"PA"`
+}
+
+type OutboundNatPolicy struct {
+ Policy
+ VIP string `json:"VIP,omitempty"`
+ Exceptions []string `json:"ExceptionList,omitempty"`
+}
+
+type ActionType string
+type DirectionType string
+type RuleType string
+
+const (
+ Allow ActionType = "Allow"
+ Block ActionType = "Block"
+
+ In DirectionType = "In"
+ Out DirectionType = "Out"
+
+ Host RuleType = "Host"
+ Switch RuleType = "Switch"
+)
+
+type ACLPolicy struct {
+ Type PolicyType `json:"Type"`
+ Protocol uint16
+ InternalPort uint16
+ Action ActionType
+ Direction DirectionType
+ LocalAddresses string
+ RemoteAddresses string
+ LocalPort uint16
+ RemotePort uint16
+ RuleType RuleType `json:"RuleType,omitempty"`
+ Priority uint16
+ ServiceName string
+}
+
+type Policy struct {
+ Type PolicyType `json:"Type"`
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
index bbd7e1e..ef1ccab 100644
--- a/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
+++ b/vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
@@ -1,200 +1,200 @@
-package hcsshim
-
-import (
- "encoding/json"
-
- "github.com/sirupsen/logrus"
-)
-
-// RoutePolicy is a structure defining schema for Route based Policy
-type RoutePolicy struct {
- Policy
- DestinationPrefix string `json:"DestinationPrefix,omitempty"`
- NextHop string `json:"NextHop,omitempty"`
- EncapEnabled bool `json:"NeedEncap,omitempty"`
-}
-
-// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
-type ELBPolicy struct {
- LBPolicy
- SourceVIP string `json:"SourceVIP,omitempty"`
- VIPs []string `json:"VIPs,omitempty"`
- ILB bool `json:"ILB,omitempty"`
-}
-
-// LBPolicy is a structure defining schema for LoadBalancing based Policy
-type LBPolicy struct {
- Policy
- Protocol uint16 `json:"Protocol,omitempty"`
- InternalPort uint16
- ExternalPort uint16
-}
-
-// PolicyList is a structure defining schema for Policy list request
-type PolicyList struct {
- ID string `json:"ID,omitempty"`
- EndpointReferences []string `json:"References,omitempty"`
- Policies []json.RawMessage `json:"Policies,omitempty"`
-}
-
-// HNSPolicyListRequest makes a call into HNS to update/query a single network
-func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
- var policy PolicyList
- err := hnsCall(method, "/policylists/"+path, request, &policy)
- if err != nil {
- return nil, err
- }
-
- return &policy, nil
-}
-
-// HNSListPolicyListRequest gets all the policy list
-func HNSListPolicyListRequest() ([]PolicyList, error) {
- var plist []PolicyList
- err := hnsCall("GET", "/policylists/", "", &plist)
- if err != nil {
- return nil, err
- }
-
- return plist, nil
-}
-
-// PolicyListRequest makes a HNS call to modify/query a network policy list
-func PolicyListRequest(method, path, request string) (*PolicyList, error) {
- policylist := &PolicyList{}
- err := hnsCall(method, "/policylists/"+path, request, &policylist)
- if err != nil {
- return nil, err
- }
-
- return policylist, nil
-}
-
-// GetPolicyListByID get the policy list by ID
-func GetPolicyListByID(policyListID string) (*PolicyList, error) {
- return PolicyListRequest("GET", policyListID, "")
-}
-
-// Create PolicyList by sending PolicyListRequest to HNS.
-func (policylist *PolicyList) Create() (*PolicyList, error) {
- operation := "Create"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" id=%s", policylist.ID)
- jsonString, err := json.Marshal(policylist)
- if err != nil {
- return nil, err
- }
- return PolicyListRequest("POST", "", string(jsonString))
-}
-
-// Delete deletes PolicyList
-func (policylist *PolicyList) Delete() (*PolicyList, error) {
- operation := "Delete"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" id=%s", policylist.ID)
-
- return PolicyListRequest("DELETE", policylist.ID, "")
-}
-
-// AddEndpoint add an endpoint to a Policy List
-func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
- operation := "AddEndpoint"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
-
- _, err := policylist.Delete()
- if err != nil {
- return nil, err
- }
-
- // Add Endpoint to the Existing List
- policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
-
- return policylist.Create()
-}
-
-// RemoveEndpoint removes an endpoint from the Policy List
-func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
- operation := "RemoveEndpoint"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
-
- _, err := policylist.Delete()
- if err != nil {
- return nil, err
- }
-
- elementToRemove := "/endpoints/" + endpoint.Id
-
- var references []string
-
- for _, endpointReference := range policylist.EndpointReferences {
- if endpointReference == elementToRemove {
- continue
- }
- references = append(references, endpointReference)
- }
- policylist.EndpointReferences = references
- return policylist.Create()
-}
-
-// AddLoadBalancer policy list for the specified endpoints
-func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
- operation := "AddLoadBalancer"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
-
- policylist := &PolicyList{}
-
- elbPolicy := &ELBPolicy{
- SourceVIP: sourceVIP,
- ILB: isILB,
- }
-
- if len(vip) > 0 {
- elbPolicy.VIPs = []string{vip}
- }
- elbPolicy.Type = ExternalLoadBalancer
- elbPolicy.Protocol = protocol
- elbPolicy.InternalPort = internalPort
- elbPolicy.ExternalPort = externalPort
-
- for _, endpoint := range endpoints {
- policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
- }
-
- jsonString, err := json.Marshal(elbPolicy)
- if err != nil {
- return nil, err
- }
- policylist.Policies = append(policylist.Policies, jsonString)
- return policylist.Create()
-}
-
-// AddRoute adds route policy list for the specified endpoints
-func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
- operation := "AddRoute"
- title := "HCSShim::PolicyList::" + operation
- logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
-
- policylist := &PolicyList{}
-
- rPolicy := &RoutePolicy{
- DestinationPrefix: destinationPrefix,
- NextHop: nextHop,
- EncapEnabled: encapEnabled,
- }
- rPolicy.Type = Route
-
- for _, endpoint := range endpoints {
- policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
- }
-
- jsonString, err := json.Marshal(rPolicy)
- if err != nil {
- return nil, err
- }
-
- policylist.Policies = append(policylist.Policies, jsonString)
- return policylist.Create()
-}
+package hcsshim
+
+import (
+ "encoding/json"
+
+ "github.com/sirupsen/logrus"
+)
+
+// RoutePolicy is a structure defining schema for Route based Policy
+type RoutePolicy struct {
+ Policy
+ DestinationPrefix string `json:"DestinationPrefix,omitempty"`
+ NextHop string `json:"NextHop,omitempty"`
+ EncapEnabled bool `json:"NeedEncap,omitempty"`
+}
+
+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy
+type ELBPolicy struct {
+ LBPolicy
+ SourceVIP string `json:"SourceVIP,omitempty"`
+ VIPs []string `json:"VIPs,omitempty"`
+ ILB bool `json:"ILB,omitempty"`
+}
+
+// LBPolicy is a structure defining schema for LoadBalancing based Policy
+type LBPolicy struct {
+ Policy
+ Protocol uint16 `json:"Protocol,omitempty"`
+ InternalPort uint16
+ ExternalPort uint16
+}
+
+// PolicyList is a structure defining schema for Policy list request
+type PolicyList struct {
+ ID string `json:"ID,omitempty"`
+ EndpointReferences []string `json:"References,omitempty"`
+ Policies []json.RawMessage `json:"Policies,omitempty"`
+}
+
+// HNSPolicyListRequest makes a call into HNS to update/query a single network
+func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
+ var policy PolicyList
+ err := hnsCall(method, "/policylists/"+path, request, &policy)
+ if err != nil {
+ return nil, err
+ }
+
+ return &policy, nil
+}
+
+// HNSListPolicyListRequest gets all the policy list
+func HNSListPolicyListRequest() ([]PolicyList, error) {
+ var plist []PolicyList
+ err := hnsCall("GET", "/policylists/", "", &plist)
+ if err != nil {
+ return nil, err
+ }
+
+ return plist, nil
+}
+
+// PolicyListRequest makes a HNS call to modify/query a network policy list
+func PolicyListRequest(method, path, request string) (*PolicyList, error) {
+ policylist := &PolicyList{}
+ err := hnsCall(method, "/policylists/"+path, request, &policylist)
+ if err != nil {
+ return nil, err
+ }
+
+ return policylist, nil
+}
+
+// GetPolicyListByID get the policy list by ID
+func GetPolicyListByID(policyListID string) (*PolicyList, error) {
+ return PolicyListRequest("GET", policyListID, "")
+}
+
+// Create PolicyList by sending PolicyListRequest to HNS.
+func (policylist *PolicyList) Create() (*PolicyList, error) {
+ operation := "Create"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s", policylist.ID)
+ jsonString, err := json.Marshal(policylist)
+ if err != nil {
+ return nil, err
+ }
+ return PolicyListRequest("POST", "", string(jsonString))
+}
+
+// Delete deletes PolicyList
+func (policylist *PolicyList) Delete() (*PolicyList, error) {
+ operation := "Delete"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s", policylist.ID)
+
+ return PolicyListRequest("DELETE", policylist.ID, "")
+}
+
+// AddEndpoint add an endpoint to a Policy List
+func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+ operation := "AddEndpoint"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+ _, err := policylist.Delete()
+ if err != nil {
+ return nil, err
+ }
+
+ // Add Endpoint to the Existing List
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+
+ return policylist.Create()
+}
+
+// RemoveEndpoint removes an endpoint from the Policy List
+func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
+ operation := "RemoveEndpoint"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id)
+
+ _, err := policylist.Delete()
+ if err != nil {
+ return nil, err
+ }
+
+ elementToRemove := "/endpoints/" + endpoint.Id
+
+ var references []string
+
+ for _, endpointReference := range policylist.EndpointReferences {
+ if endpointReference == elementToRemove {
+ continue
+ }
+ references = append(references, endpointReference)
+ }
+ policylist.EndpointReferences = references
+ return policylist.Create()
+}
+
+// AddLoadBalancer policy list for the specified endpoints
+func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
+ operation := "AddLoadBalancer"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
+
+ policylist := &PolicyList{}
+
+ elbPolicy := &ELBPolicy{
+ SourceVIP: sourceVIP,
+ ILB: isILB,
+ }
+
+ if len(vip) > 0 {
+ elbPolicy.VIPs = []string{vip}
+ }
+ elbPolicy.Type = ExternalLoadBalancer
+ elbPolicy.Protocol = protocol
+ elbPolicy.InternalPort = internalPort
+ elbPolicy.ExternalPort = externalPort
+
+ for _, endpoint := range endpoints {
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+ }
+
+ jsonString, err := json.Marshal(elbPolicy)
+ if err != nil {
+ return nil, err
+ }
+ policylist.Policies = append(policylist.Policies, jsonString)
+ return policylist.Create()
+}
+
+// AddRoute adds route policy list for the specified endpoints
+func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
+ operation := "AddRoute"
+ title := "HCSShim::PolicyList::" + operation
+ logrus.Debugf(title+" destinationPrefix:%s", destinationPrefix)
+
+ policylist := &PolicyList{}
+
+ rPolicy := &RoutePolicy{
+ DestinationPrefix: destinationPrefix,
+ NextHop: nextHop,
+ EncapEnabled: encapEnabled,
+ }
+ rPolicy.Type = Route
+
+ for _, endpoint := range endpoints {
+ policylist.EndpointReferences = append(policylist.EndpointReferences, "/endpoints/"+endpoint.Id)
+ }
+
+ jsonString, err := json.Marshal(rPolicy)
+ if err != nil {
+ return nil, err
+ }
+
+ policylist.Policies = append(policylist.Policies, jsonString)
+ return policylist.Create()
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/importlayer.go b/vendor/github.com/Microsoft/hcsshim/importlayer.go
index 3aed143..2742b9f 100644
--- a/vendor/github.com/Microsoft/hcsshim/importlayer.go
+++ b/vendor/github.com/Microsoft/hcsshim/importlayer.go
@@ -129,37 +129,39 @@
}
func (r *legacyLayerWriterWrapper) Close() error {
- defer os.RemoveAll(r.root)
+ defer os.RemoveAll(r.root.Name())
+ defer r.legacyLayerWriter.CloseRoots()
err := r.legacyLayerWriter.Close()
if err != nil {
return err
}
- // Use the original path here because ImportLayer does not support long paths for the source in TP5.
- // But do use a long path for the destination to work around another bug with directories
- // with MAX_PATH - 12 < length < MAX_PATH.
info := r.info
- fullPath, err := makeLongAbsPath(filepath.Join(info.HomeDir, r.layerID))
- if err != nil {
+ info.HomeDir = ""
+ if err = ImportLayer(info, r.destRoot.Name(), r.path, r.parentLayerPaths); err != nil {
return err
}
-
- info.HomeDir = ""
- if err = ImportLayer(info, fullPath, r.path, r.parentLayerPaths); err != nil {
- return err
+ for _, name := range r.Tombstones {
+ if err = removeRelative(name, r.destRoot); err != nil && !os.IsNotExist(err) {
+ return err
+ }
}
// Add any hard links that were collected.
for _, lnk := range r.PendingLinks {
- if err = os.Remove(lnk.Path); err != nil && !os.IsNotExist(err) {
+ if err = removeRelative(lnk.Path, r.destRoot); err != nil && !os.IsNotExist(err) {
return err
}
- if err = os.Link(lnk.Target, lnk.Path); err != nil {
+ if err = linkRelative(lnk.Target, lnk.TargetRoot, lnk.Path, r.destRoot); err != nil {
return err
}
}
// Prepare the utility VM for use if one is present in the layer.
if r.HasUtilityVM {
- err = ProcessUtilityVMImage(filepath.Join(fullPath, "UtilityVM"))
+ err := ensureNotReparsePointRelative("UtilityVM", r.destRoot)
+ if err != nil {
+ return err
+ }
+ err = ProcessUtilityVMImage(filepath.Join(r.destRoot.Name(), "UtilityVM"))
if err != nil {
return err
}
@@ -173,8 +175,12 @@
func NewLayerWriter(info DriverInfo, layerID string, parentLayerPaths []string) (LayerWriter, error) {
if len(parentLayerPaths) == 0 {
// This is a base layer. It gets imported differently.
+ f, err := openRoot(filepath.Join(info.HomeDir, layerID))
+ if err != nil {
+ return nil, err
+ }
return &baseLayerWriter{
- root: filepath.Join(info.HomeDir, layerID),
+ root: f,
}, nil
}
@@ -185,8 +191,12 @@
if err != nil {
return nil, err
}
+ w, err := newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID))
+ if err != nil {
+ return nil, err
+ }
return &legacyLayerWriterWrapper{
- legacyLayerWriter: newLegacyLayerWriter(path, parentLayerPaths, filepath.Join(info.HomeDir, layerID)),
+ legacyLayerWriter: w,
info: info,
layerID: layerID,
path: path,
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy.go b/vendor/github.com/Microsoft/hcsshim/legacy.go
index 673a4f8..85c7791 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy.go
@@ -336,59 +336,79 @@
type pendingLink struct {
Path, Target string
+ TargetRoot *os.File
+}
+
+type pendingDir struct {
+ Path string
+ Root *os.File
}
type legacyLayerWriter struct {
- root string
- parentRoots []string
- destRoot string
- currentFile *os.File
- backupWriter *winio.BackupFileWriter
- tombstones []string
- pathFixed bool
- HasUtilityVM bool
- uvmDi []dirInfo
- addedFiles map[string]bool
- PendingLinks []pendingLink
+ root *os.File
+ destRoot *os.File
+ parentRoots []*os.File
+ currentFile *os.File
+ currentFileName string
+ currentFileRoot *os.File
+ backupWriter *winio.BackupFileWriter
+ Tombstones []string
+ HasUtilityVM bool
+ uvmDi []dirInfo
+ addedFiles map[string]bool
+ PendingLinks []pendingLink
+ pendingDirs []pendingDir
+ currentIsDir bool
}
// newLegacyLayerWriter returns a LayerWriter that can write the contaler layer
// transport format to disk.
-func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) *legacyLayerWriter {
- return &legacyLayerWriter{
- root: root,
- parentRoots: parentRoots,
- destRoot: destRoot,
- addedFiles: make(map[string]bool),
+func newLegacyLayerWriter(root string, parentRoots []string, destRoot string) (w *legacyLayerWriter, err error) {
+ w = &legacyLayerWriter{
+ addedFiles: make(map[string]bool),
}
+ defer func() {
+ if err != nil {
+ w.CloseRoots()
+ w = nil
+ }
+ }()
+ w.root, err = openRoot(root)
+ if err != nil {
+ return
+ }
+ w.destRoot, err = openRoot(destRoot)
+ if err != nil {
+ return
+ }
+ for _, r := range parentRoots {
+ f, err := openRoot(r)
+ if err != nil {
+ return w, err
+ }
+ w.parentRoots = append(w.parentRoots, f)
+ }
+ return
}
-func (w *legacyLayerWriter) init() error {
- if !w.pathFixed {
- path, err := makeLongAbsPath(w.root)
- if err != nil {
- return err
- }
- for i, p := range w.parentRoots {
- w.parentRoots[i], err = makeLongAbsPath(p)
- if err != nil {
- return err
- }
- }
- destPath, err := makeLongAbsPath(w.destRoot)
- if err != nil {
- return err
- }
- w.root = path
- w.destRoot = destPath
- w.pathFixed = true
+func (w *legacyLayerWriter) CloseRoots() {
+ if w.root != nil {
+ w.root.Close()
+ w.root = nil
}
- return nil
+ if w.destRoot != nil {
+ w.destRoot.Close()
+ w.destRoot = nil
+ }
+ for i := range w.parentRoots {
+ w.parentRoots[i].Close()
+ }
+ w.parentRoots = nil
}
func (w *legacyLayerWriter) initUtilityVM() error {
if !w.HasUtilityVM {
- err := os.Mkdir(filepath.Join(w.destRoot, utilityVMPath), 0)
+ err := mkdirRelative(utilityVMPath, w.destRoot)
if err != nil {
return err
}
@@ -396,7 +416,7 @@
// clone the utility VM from the parent layer into this layer. Use hard
// links to avoid unnecessary copying, since most of the files are
// immutable.
- err = cloneTree(filepath.Join(w.parentRoots[0], utilityVMFilesPath), filepath.Join(w.destRoot, utilityVMFilesPath), mutatedUtilityVMFiles)
+ err = cloneTree(w.parentRoots[0], w.destRoot, utilityVMFilesPath, mutatedUtilityVMFiles)
if err != nil {
return fmt.Errorf("cloning the parent utility VM image failed: %s", err)
}
@@ -405,7 +425,40 @@
return nil
}
-func (w *legacyLayerWriter) reset() {
+func (w *legacyLayerWriter) reset() error {
+ if w.currentIsDir {
+ r := w.currentFile
+ br := winio.NewBackupStreamReader(r)
+ // Seek to the beginning of the backup stream, skipping the fileattrs
+ if _, err := r.Seek(4, io.SeekStart); err != nil {
+ return err
+ }
+
+ for {
+ bhdr, err := br.Next()
+ if err == io.EOF {
+ // end of backupstream data
+ break
+ }
+ if err != nil {
+ return err
+ }
+ switch bhdr.Id {
+ case winio.BackupReparseData:
+ // The current file is a `.$wcidirs$` metadata file that
+ // describes a directory reparse point. Delete the placeholder
+ // directory to prevent future files being added into the
+ // destination of the reparse point during the ImportLayer call
+ if err := removeRelative(w.currentFileName, w.currentFileRoot); err != nil {
+ return err
+ }
+ w.pendingDirs = append(w.pendingDirs, pendingDir{Path: w.currentFileName, Root: w.currentFileRoot})
+ default:
+ // ignore all other stream types, as we only care about directory reparse points
+ }
+ }
+ w.currentIsDir = false
+ }
if w.backupWriter != nil {
w.backupWriter.Close()
w.backupWriter = nil
@@ -413,21 +466,21 @@
if w.currentFile != nil {
w.currentFile.Close()
w.currentFile = nil
+ w.currentFileName = ""
+ w.currentFileRoot = nil
}
+ return nil
}
// copyFileWithMetadata copies a file using the backup/restore APIs in order to preserve metadata
-func copyFileWithMetadata(srcPath, destPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
- createDisposition := uint32(syscall.CREATE_NEW)
- if isDir {
- err = os.Mkdir(destPath, 0)
- if err != nil {
- return nil, err
- }
- createDisposition = syscall.OPEN_EXISTING
- }
-
- src, err := openFileOrDir(srcPath, syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY, syscall.OPEN_EXISTING)
+func copyFileWithMetadata(srcRoot, destRoot *os.File, subPath string, isDir bool) (fileInfo *winio.FileBasicInfo, err error) {
+ src, err := openRelative(
+ subPath,
+ srcRoot,
+ syscall.GENERIC_READ|winio.ACCESS_SYSTEM_SECURITY,
+ syscall.FILE_SHARE_READ,
+ _FILE_OPEN,
+ _FILE_OPEN_REPARSE_POINT)
if err != nil {
return nil, err
}
@@ -440,7 +493,17 @@
return nil, err
}
- dest, err := openFileOrDir(destPath, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
+ extraFlags := uint32(0)
+ if isDir {
+ extraFlags |= _FILE_DIRECTORY_FILE
+ }
+ dest, err := openRelative(
+ subPath,
+ destRoot,
+ syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
+ syscall.FILE_SHARE_READ,
+ _FILE_CREATE,
+ extraFlags)
if err != nil {
return nil, err
}
@@ -469,18 +532,21 @@
// cloneTree clones a directory tree using hard links. It skips hard links for
// the file names in the provided map and just copies those files.
-func cloneTree(srcPath, destPath string, mutatedFiles map[string]bool) error {
+func cloneTree(srcRoot *os.File, destRoot *os.File, subPath string, mutatedFiles map[string]bool) error {
var di []dirInfo
- err := filepath.Walk(srcPath, func(srcFilePath string, info os.FileInfo, err error) error {
+ err := ensureNotReparsePointRelative(subPath, srcRoot)
+ if err != nil {
+ return err
+ }
+ err = filepath.Walk(filepath.Join(srcRoot.Name(), subPath), func(srcFilePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
- relPath, err := filepath.Rel(srcPath, srcFilePath)
+ relPath, err := filepath.Rel(srcRoot.Name(), srcFilePath)
if err != nil {
return err
}
- destFilePath := filepath.Join(destPath, relPath)
fileAttributes := info.Sys().(*syscall.Win32FileAttributeData).FileAttributes
// Directories, reparse points, and files that will be mutated during
@@ -492,15 +558,15 @@
isDir := fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0
if isDir || isReparsePoint || mutatedFiles[relPath] {
- fi, err := copyFileWithMetadata(srcFilePath, destFilePath, isDir)
+ fi, err := copyFileWithMetadata(srcRoot, destRoot, relPath, isDir)
if err != nil {
return err
}
if isDir && !isReparsePoint {
- di = append(di, dirInfo{path: destFilePath, fileInfo: *fi})
+ di = append(di, dirInfo{path: relPath, fileInfo: *fi})
}
} else {
- err = os.Link(srcFilePath, destFilePath)
+ err = linkRelative(relPath, srcRoot, relPath, destRoot)
if err != nil {
return err
}
@@ -518,13 +584,11 @@
return err
}
- return reapplyDirectoryTimes(di)
+ return reapplyDirectoryTimes(destRoot, di)
}
func (w *legacyLayerWriter) Add(name string, fileInfo *winio.FileBasicInfo) error {
- w.reset()
- err := w.init()
- if err != nil {
+ if err := w.reset(); err != nil {
return err
}
@@ -532,6 +596,7 @@
return w.initUtilityVM()
}
+ name = filepath.Clean(name)
if hasPathPrefix(name, utilityVMPath) {
if !w.HasUtilityVM {
return errors.New("missing UtilityVM directory")
@@ -539,10 +604,9 @@
if !hasPathPrefix(name, utilityVMFilesPath) && name != utilityVMFilesPath {
return errors.New("invalid UtilityVM layer")
}
- path := filepath.Join(w.destRoot, name)
- createDisposition := uint32(syscall.OPEN_EXISTING)
+ createDisposition := uint32(_FILE_OPEN)
if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
- st, err := os.Lstat(path)
+ st, err := lstatRelative(name, w.destRoot)
if err != nil && !os.IsNotExist(err) {
return err
}
@@ -550,37 +614,44 @@
// Delete the existing file/directory if it is not the same type as this directory.
existingAttr := st.Sys().(*syscall.Win32FileAttributeData).FileAttributes
if (uint32(fileInfo.FileAttributes)^existingAttr)&(syscall.FILE_ATTRIBUTE_DIRECTORY|syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
- if err = os.RemoveAll(path); err != nil {
+ if err = removeAllRelative(name, w.destRoot); err != nil {
return err
}
st = nil
}
}
if st == nil {
- if err = os.Mkdir(path, 0); err != nil {
+ if err = mkdirRelative(name, w.destRoot); err != nil {
return err
}
}
if fileInfo.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
- w.uvmDi = append(w.uvmDi, dirInfo{path: path, fileInfo: *fileInfo})
+ w.uvmDi = append(w.uvmDi, dirInfo{path: name, fileInfo: *fileInfo})
}
} else {
// Overwrite any existing hard link.
- err = os.Remove(path)
+ err := removeRelative(name, w.destRoot)
if err != nil && !os.IsNotExist(err) {
return err
}
- createDisposition = syscall.CREATE_NEW
+ createDisposition = _FILE_CREATE
}
- f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY, createDisposition)
+ f, err := openRelative(
+ name,
+ w.destRoot,
+ syscall.GENERIC_READ|syscall.GENERIC_WRITE|winio.WRITE_DAC|winio.WRITE_OWNER|winio.ACCESS_SYSTEM_SECURITY,
+ syscall.FILE_SHARE_READ,
+ createDisposition,
+ _FILE_OPEN_REPARSE_POINT,
+ )
if err != nil {
return err
}
defer func() {
if f != nil {
f.Close()
- os.Remove(path)
+ removeRelative(name, w.destRoot)
}
}()
@@ -591,28 +662,31 @@
w.backupWriter = winio.NewBackupFileWriter(f, true)
w.currentFile = f
+ w.currentFileName = name
+ w.currentFileRoot = w.destRoot
w.addedFiles[name] = true
f = nil
return nil
}
- path := filepath.Join(w.root, name)
+ fname := name
if (fileInfo.FileAttributes & syscall.FILE_ATTRIBUTE_DIRECTORY) != 0 {
- err := os.Mkdir(path, 0)
+ err := mkdirRelative(name, w.root)
if err != nil {
return err
}
- path += ".$wcidirs$"
+ fname += ".$wcidirs$"
+ w.currentIsDir = true
}
- f, err := openFileOrDir(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.CREATE_NEW)
+ f, err := openRelative(fname, w.root, syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ, _FILE_CREATE, 0)
if err != nil {
return err
}
defer func() {
if f != nil {
f.Close()
- os.Remove(path)
+ removeRelative(fname, w.root)
}
}()
@@ -634,19 +708,20 @@
}
w.currentFile = f
+ w.currentFileName = name
+ w.currentFileRoot = w.root
w.addedFiles[name] = true
f = nil
return nil
}
func (w *legacyLayerWriter) AddLink(name string, target string) error {
- w.reset()
- err := w.init()
- if err != nil {
+ if err := w.reset(); err != nil {
return err
}
- var roots []string
+ target = filepath.Clean(target)
+ var roots []*os.File
if hasPathPrefix(target, filesPath) {
// Look for cross-layer hard link targets in the parent layers, since
// nothing is in the destination path yet.
@@ -655,7 +730,7 @@
// Since the utility VM is fully cloned into the destination path
// already, look for cross-layer hard link targets directly in the
// destination path.
- roots = []string{w.destRoot}
+ roots = []*os.File{w.destRoot}
}
if roots == nil || (!hasPathPrefix(name, filesPath) && !hasPathPrefix(name, utilityVMFilesPath)) {
@@ -664,12 +739,12 @@
// Find to try the target of the link in a previously added file. If that
// fails, search in parent layers.
- var selectedRoot string
+ var selectedRoot *os.File
if _, ok := w.addedFiles[target]; ok {
selectedRoot = w.destRoot
} else {
for _, r := range roots {
- if _, err = os.Lstat(filepath.Join(r, target)); err != nil {
+ if _, err := lstatRelative(target, r); err != nil {
if !os.IsNotExist(err) {
return err
}
@@ -678,22 +753,25 @@
break
}
}
- if selectedRoot == "" {
+ if selectedRoot == nil {
return fmt.Errorf("failed to find link target for '%s' -> '%s'", name, target)
}
}
+
// The link can't be written until after the ImportLayer call.
w.PendingLinks = append(w.PendingLinks, pendingLink{
- Path: filepath.Join(w.destRoot, name),
- Target: filepath.Join(selectedRoot, target),
+ Path: name,
+ Target: target,
+ TargetRoot: selectedRoot,
})
w.addedFiles[name] = true
return nil
}
func (w *legacyLayerWriter) Remove(name string) error {
+ name = filepath.Clean(name)
if hasPathPrefix(name, filesPath) {
- w.tombstones = append(w.tombstones, name[len(filesPath)+1:])
+ w.Tombstones = append(w.Tombstones, name)
} else if hasPathPrefix(name, utilityVMFilesPath) {
err := w.initUtilityVM()
if err != nil {
@@ -702,11 +780,10 @@
// Make sure the path exists; os.RemoveAll will not fail if the file is
// already gone, and this needs to be a fatal error for diagnostics
// purposes.
- path := filepath.Join(w.destRoot, name)
- if _, err := os.Lstat(path); err != nil {
+ if _, err := lstatRelative(name, w.destRoot); err != nil {
return err
}
- err = os.RemoveAll(path)
+ err = removeAllRelative(name, w.destRoot)
if err != nil {
return err
}
@@ -728,28 +805,20 @@
}
func (w *legacyLayerWriter) Close() error {
- w.reset()
- err := w.init()
- if err != nil {
+ if err := w.reset(); err != nil {
return err
}
- tf, err := os.Create(filepath.Join(w.root, "tombstones.txt"))
- if err != nil {
+ if err := removeRelative("tombstones.txt", w.root); err != nil && !os.IsNotExist(err) {
return err
}
- defer tf.Close()
- _, err = tf.Write([]byte("\xef\xbb\xbfVersion 1.0\n"))
- if err != nil {
- return err
- }
- for _, t := range w.tombstones {
- _, err = tf.Write([]byte(filepath.Join(`\`, t) + "\n"))
+ for _, pd := range w.pendingDirs {
+ err := mkdirRelative(pd.Path, pd.Root)
if err != nil {
return err
}
}
if w.HasUtilityVM {
- err = reapplyDirectoryTimes(w.uvmDi)
+ err := reapplyDirectoryTimes(w.destRoot, w.uvmDi)
if err != nil {
return err
}
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy18.go b/vendor/github.com/Microsoft/hcsshim/legacy18.go
index 578552f..0f593e8 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy18.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy18.go
@@ -1,7 +1,7 @@
-// +build !go1.9
-
-package hcsshim
-
-// Due to a bug in go1.8 and before, directory reparse points need to be skipped
-// during filepath.Walk. This is fixed in go1.9
-var shouldSkipDirectoryReparse = true
+// +build !go1.9
+
+package hcsshim
+
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
+// during filepath.Walk. This is fixed in go1.9
+var shouldSkipDirectoryReparse = true
diff --git a/vendor/github.com/Microsoft/hcsshim/legacy19.go b/vendor/github.com/Microsoft/hcsshim/legacy19.go
index 6aa1dc0..fb0b764 100644
--- a/vendor/github.com/Microsoft/hcsshim/legacy19.go
+++ b/vendor/github.com/Microsoft/hcsshim/legacy19.go
@@ -1,7 +1,7 @@
-// +build go1.9
-
-package hcsshim
-
-// Due to a bug in go1.8 and before, directory reparse points need to be skipped
-// during filepath.Walk. This is fixed in go1.9
-var shouldSkipDirectoryReparse = false
+// +build go1.9
+
+package hcsshim
+
+// Due to a bug in go1.8 and before, directory reparse points need to be skipped
+// during filepath.Walk. This is fixed in go1.9
+var shouldSkipDirectoryReparse = false
diff --git a/vendor/github.com/Microsoft/hcsshim/safeopen.go b/vendor/github.com/Microsoft/hcsshim/safeopen.go
new file mode 100644
index 0000000..5356456
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/safeopen.go
@@ -0,0 +1,427 @@
+package hcsshim
+
+import (
+ "errors"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+ "syscall"
+ "unicode/utf16"
+ "unsafe"
+
+ winio "github.com/Microsoft/go-winio"
+)
+
+//sys ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) = ntdll.NtCreateFile
+//sys ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) = ntdll.NtSetInformationFile
+//sys rtlNtStatusToDosError(status uint32) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
+//sys localAlloc(flags uint32, size int) (ptr uintptr) = kernel32.LocalAlloc
+//sys localFree(ptr uintptr) = kernel32.LocalFree
+
+type ioStatusBlock struct {
+ Status, Information uintptr
+}
+
+type objectAttributes struct {
+ Length uintptr
+ RootDirectory uintptr
+ ObjectName uintptr
+ Attributes uintptr
+ SecurityDescriptor uintptr
+ SecurityQoS uintptr
+}
+
+type unicodeString struct {
+ Length uint16
+ MaximumLength uint16
+ Buffer uintptr
+}
+
+type fileLinkInformation struct {
+ ReplaceIfExists bool
+ RootDirectory uintptr
+ FileNameLength uint32
+ FileName [1]uint16
+}
+
+type fileDispositionInformationEx struct {
+ Flags uintptr
+}
+
+const (
+ _FileLinkInformation = 11
+ _FileDispositionInformationEx = 64
+
+ _FILE_READ_ATTRIBUTES = 0x0080
+ _FILE_WRITE_ATTRIBUTES = 0x0100
+ _DELETE = 0x10000
+
+ _FILE_OPEN = 1
+ _FILE_CREATE = 2
+
+ _FILE_DIRECTORY_FILE = 0x00000001
+ _FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020
+ _FILE_DELETE_ON_CLOSE = 0x00001000
+ _FILE_OPEN_FOR_BACKUP_INTENT = 0x00004000
+ _FILE_OPEN_REPARSE_POINT = 0x00200000
+
+ _FILE_DISPOSITION_DELETE = 0x00000001
+
+ _OBJ_DONT_REPARSE = 0x1000
+
+ _STATUS_REPARSE_POINT_ENCOUNTERED = 0xC000050B
+)
+
+func openRoot(path string) (*os.File, error) {
+ longpath, err := makeLongAbsPath(path)
+ if err != nil {
+ return nil, err
+ }
+ return winio.OpenForBackup(longpath, syscall.GENERIC_READ, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, syscall.OPEN_EXISTING)
+}
+
+func ntRelativePath(path string) ([]uint16, error) {
+ path = filepath.Clean(path)
+ if strings.Contains(":", path) {
+ // Since alternate data streams must follow the file they
+ // are attached to, finding one here (out of order) is invalid.
+ return nil, errors.New("path contains invalid character `:`")
+ }
+ fspath := filepath.FromSlash(path)
+ if len(fspath) > 0 && fspath[0] == '\\' {
+ return nil, errors.New("expected relative path")
+ }
+
+ path16 := utf16.Encode(([]rune)(fspath))
+ if len(path16) > 32767 {
+ return nil, syscall.ENAMETOOLONG
+ }
+
+ return path16, nil
+}
+
+// openRelativeInternal opens a relative path from the given root, failing if
+// any of the intermediate path components are reparse points.
+func openRelativeInternal(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
+ var (
+ h uintptr
+ iosb ioStatusBlock
+ oa objectAttributes
+ )
+
+ path16, err := ntRelativePath(path)
+ if err != nil {
+ return nil, err
+ }
+
+ if root == nil || root.Fd() == 0 {
+ return nil, errors.New("missing root directory")
+ }
+
+ upathBuffer := localAlloc(0, int(unsafe.Sizeof(unicodeString{}))+len(path16)*2)
+ defer localFree(upathBuffer)
+
+ upath := (*unicodeString)(unsafe.Pointer(upathBuffer))
+ upath.Length = uint16(len(path16) * 2)
+ upath.MaximumLength = upath.Length
+ upath.Buffer = upathBuffer + unsafe.Sizeof(*upath)
+ copy((*[32768]uint16)(unsafe.Pointer(upath.Buffer))[:], path16)
+
+ oa.Length = unsafe.Sizeof(oa)
+ oa.ObjectName = upathBuffer
+ oa.RootDirectory = uintptr(root.Fd())
+ oa.Attributes = _OBJ_DONT_REPARSE
+ status := ntCreateFile(
+ &h,
+ accessMask|syscall.SYNCHRONIZE,
+ &oa,
+ &iosb,
+ nil,
+ 0,
+ shareFlags,
+ createDisposition,
+ _FILE_OPEN_FOR_BACKUP_INTENT|_FILE_SYNCHRONOUS_IO_NONALERT|flags,
+ nil,
+ 0,
+ )
+ if status != 0 {
+ return nil, rtlNtStatusToDosError(status)
+ }
+
+ fullPath, err := makeLongAbsPath(filepath.Join(root.Name(), path))
+ if err != nil {
+ syscall.Close(syscall.Handle(h))
+ return nil, err
+ }
+
+ return os.NewFile(h, fullPath), nil
+}
+
+// openRelative opens a relative path from the given root, failing if
+// any of the intermediate path components are reparse points.
+func openRelative(path string, root *os.File, accessMask uint32, shareFlags uint32, createDisposition uint32, flags uint32) (*os.File, error) {
+ f, err := openRelativeInternal(path, root, accessMask, shareFlags, createDisposition, flags)
+ if err != nil {
+ err = &os.PathError{Op: "open", Path: filepath.Join(root.Name(), path), Err: err}
+ }
+ return f, err
+}
+
+// linkRelative creates a hard link from oldname to newname (relative to oldroot
+// and newroot), failing if any of the intermediate path components are reparse
+// points.
+func linkRelative(oldname string, oldroot *os.File, newname string, newroot *os.File) error {
+ // Open the old file.
+ oldf, err := openRelativeInternal(
+ oldname,
+ oldroot,
+ syscall.FILE_WRITE_ATTRIBUTES,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_OPEN,
+ 0,
+ )
+ if err != nil {
+ return &os.LinkError{Op: "link", Old: filepath.Join(oldroot.Name(), oldname), New: filepath.Join(newroot.Name(), newname), Err: err}
+ }
+ defer oldf.Close()
+
+ // Open the parent of the new file.
+ var parent *os.File
+ parentPath := filepath.Dir(newname)
+ if parentPath != "." {
+ parent, err = openRelativeInternal(
+ parentPath,
+ newroot,
+ syscall.GENERIC_READ,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_OPEN,
+ _FILE_DIRECTORY_FILE)
+ if err != nil {
+ return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: err}
+ }
+ defer parent.Close()
+
+ fi, err := winio.GetFileBasicInfo(parent)
+ if err != nil {
+ return err
+ }
+ if (fi.FileAttributes & syscall.FILE_ATTRIBUTE_REPARSE_POINT) != 0 {
+ return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(newroot.Name(), newname), Err: rtlNtStatusToDosError(_STATUS_REPARSE_POINT_ENCOUNTERED)}
+ }
+
+ } else {
+ parent = newroot
+ }
+
+ // Issue an NT call to create the link. This will be safe because NT will
+ // not open any more directories to create the link, so it cannot walk any
+ // more reparse points.
+ newbase := filepath.Base(newname)
+ newbase16, err := ntRelativePath(newbase)
+ if err != nil {
+ return err
+ }
+
+ size := int(unsafe.Offsetof(fileLinkInformation{}.FileName)) + len(newbase16)*2
+ linkinfoBuffer := localAlloc(0, size)
+ defer localFree(linkinfoBuffer)
+ linkinfo := (*fileLinkInformation)(unsafe.Pointer(linkinfoBuffer))
+ linkinfo.RootDirectory = parent.Fd()
+ linkinfo.FileNameLength = uint32(len(newbase16) * 2)
+ copy((*[32768]uint16)(unsafe.Pointer(&linkinfo.FileName[0]))[:], newbase16)
+
+ var iosb ioStatusBlock
+ status := ntSetInformationFile(
+ oldf.Fd(),
+ &iosb,
+ linkinfoBuffer,
+ uint32(size),
+ _FileLinkInformation,
+ )
+ if status != 0 {
+ return &os.LinkError{Op: "link", Old: oldf.Name(), New: filepath.Join(parent.Name(), newbase), Err: rtlNtStatusToDosError(status)}
+ }
+
+ return nil
+}
+
+// deleteOnClose marks a file to be deleted when the handle is closed.
+func deleteOnClose(f *os.File) error {
+ disposition := fileDispositionInformationEx{Flags: _FILE_DISPOSITION_DELETE}
+ var iosb ioStatusBlock
+ status := ntSetInformationFile(
+ f.Fd(),
+ &iosb,
+ uintptr(unsafe.Pointer(&disposition)),
+ uint32(unsafe.Sizeof(disposition)),
+ _FileDispositionInformationEx,
+ )
+ if status != 0 {
+ return rtlNtStatusToDosError(status)
+ }
+ return nil
+}
+
+// clearReadOnly clears the readonly attribute on a file.
+func clearReadOnly(f *os.File) error {
+ bi, err := winio.GetFileBasicInfo(f)
+ if err != nil {
+ return err
+ }
+ if bi.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY == 0 {
+ return nil
+ }
+ sbi := winio.FileBasicInfo{
+ FileAttributes: bi.FileAttributes &^ syscall.FILE_ATTRIBUTE_READONLY,
+ }
+ if sbi.FileAttributes == 0 {
+ sbi.FileAttributes = syscall.FILE_ATTRIBUTE_NORMAL
+ }
+ return winio.SetFileBasicInfo(f, &sbi)
+}
+
+// removeRelative removes a file or directory relative to a root, failing if any
+// intermediate path components are reparse points.
+func removeRelative(path string, root *os.File) error {
+ f, err := openRelativeInternal(
+ path,
+ root,
+ _FILE_READ_ATTRIBUTES|_FILE_WRITE_ATTRIBUTES|_DELETE,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_OPEN,
+ _FILE_OPEN_REPARSE_POINT)
+ if err == nil {
+ defer f.Close()
+ err = deleteOnClose(f)
+ if err == syscall.ERROR_ACCESS_DENIED {
+ // Maybe the file is marked readonly. Clear the bit and retry.
+ clearReadOnly(f)
+ err = deleteOnClose(f)
+ }
+ }
+ if err != nil {
+ return &os.PathError{Op: "remove", Path: filepath.Join(root.Name(), path), Err: err}
+ }
+ return nil
+}
+
+// removeAllRelative removes a directory tree relative to a root, failing if any
+// intermediate path components are reparse points.
+func removeAllRelative(path string, root *os.File) error {
+ fi, err := lstatRelative(path, root)
+ if err != nil {
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+ fileAttributes := fi.Sys().(*syscall.Win32FileAttributeData).FileAttributes
+ if fileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 || fileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ // If this is a reparse point, it can't have children. Simple remove will do.
+ err := removeRelative(path, root)
+ if err == nil || os.IsNotExist(err) {
+ return nil
+ }
+ return err
+ }
+
+ // It is necessary to use os.Open as Readdirnames does not work with
+ // openRelative. This is safe because the above lstatrelative fails
+ // if the target is outside the root, and we know this is not a
+ // symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
+ fd, err := os.Open(filepath.Join(root.Name(), path))
+ if err != nil {
+ if os.IsNotExist(err) {
+ // Race. It was deleted between the Lstat and Open.
+ // Return nil per RemoveAll's docs.
+ return nil
+ }
+ return err
+ }
+
+ // Remove contents & return first error.
+ for {
+ names, err1 := fd.Readdirnames(100)
+ for _, name := range names {
+ err1 := removeAllRelative(path+string(os.PathSeparator)+name, root)
+ if err == nil {
+ err = err1
+ }
+ }
+ if err1 == io.EOF {
+ break
+ }
+ // If Readdirnames returned an error, use it.
+ if err == nil {
+ err = err1
+ }
+ if len(names) == 0 {
+ break
+ }
+ }
+ fd.Close()
+
+ // Remove directory.
+ err1 := removeRelative(path, root)
+ if err1 == nil || os.IsNotExist(err1) {
+ return nil
+ }
+ if err == nil {
+ err = err1
+ }
+ return err
+}
+
+// mkdirRelative creates a directory relative to a root, failing if any
+// intermediate path components are reparse points.
+func mkdirRelative(path string, root *os.File) error {
+ f, err := openRelativeInternal(
+ path,
+ root,
+ 0,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_CREATE,
+ _FILE_DIRECTORY_FILE)
+ if err == nil {
+ f.Close()
+ } else {
+ err = &os.PathError{Op: "mkdir", Path: filepath.Join(root.Name(), path), Err: err}
+ }
+ return err
+}
+
+// lstatRelative performs a stat operation on a file relative to a root, failing
+// if any intermediate path components are reparse points.
+func lstatRelative(path string, root *os.File) (os.FileInfo, error) {
+ f, err := openRelativeInternal(
+ path,
+ root,
+ _FILE_READ_ATTRIBUTES,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_OPEN,
+ _FILE_OPEN_REPARSE_POINT)
+ if err != nil {
+ return nil, &os.PathError{Op: "stat", Path: filepath.Join(root.Name(), path), Err: err}
+ }
+ defer f.Close()
+ return f.Stat()
+}
+
+// ensureNotReparsePointRelative validates that a given file (relative to a
+// root) and all intermediate path components are not a reparse points.
+func ensureNotReparsePointRelative(path string, root *os.File) error {
+ // Perform an open with OBJ_DONT_REPARSE but without specifying FILE_OPEN_REPARSE_POINT.
+ f, err := openRelative(
+ path,
+ root,
+ 0,
+ syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
+ _FILE_OPEN,
+ 0)
+ if err != nil {
+ return err
+ }
+ f.Close()
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/zhcsshim.go b/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
index 5d1a851..5123e8d 100644
--- a/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
+++ b/vendor/github.com/Microsoft/hcsshim/zhcsshim.go
@@ -41,6 +41,8 @@
modole32 = windows.NewLazySystemDLL("ole32.dll")
modiphlpapi = windows.NewLazySystemDLL("iphlpapi.dll")
modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+ modntdll = windows.NewLazySystemDLL("ntdll.dll")
+ modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procCoTaskMemFree = modole32.NewProc("CoTaskMemFree")
procSetCurrentThreadCompartmentId = modiphlpapi.NewProc("SetCurrentThreadCompartmentId")
@@ -94,6 +96,11 @@
procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
procHcsModifyServiceSettings = modvmcompute.NewProc("HcsModifyServiceSettings")
procHNSCall = modvmcompute.NewProc("HNSCall")
+ procNtCreateFile = modntdll.NewProc("NtCreateFile")
+ procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
+ procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
+ procLocalAlloc = modkernel32.NewProc("LocalAlloc")
+ procLocalFree = modkernel32.NewProc("LocalFree")
)
func coTaskMemFree(buffer unsafe.Pointer) {
@@ -1040,3 +1047,34 @@
}
return
}
+
+func ntCreateFile(handle *uintptr, accessMask uint32, oa *objectAttributes, iosb *ioStatusBlock, allocationSize *uint64, fileAttributes uint32, shareAccess uint32, createDisposition uint32, createOptions uint32, eaBuffer *byte, eaLength uint32) (status uint32) {
+ r0, _, _ := syscall.Syscall12(procNtCreateFile.Addr(), 11, uintptr(unsafe.Pointer(handle)), uintptr(accessMask), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(allocationSize)), uintptr(fileAttributes), uintptr(shareAccess), uintptr(createDisposition), uintptr(createOptions), uintptr(unsafe.Pointer(eaBuffer)), uintptr(eaLength), 0)
+ status = uint32(r0)
+ return
+}
+
+func ntSetInformationFile(handle uintptr, iosb *ioStatusBlock, information uintptr, length uint32, class uint32) (status uint32) {
+ r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(information), uintptr(length), uintptr(class), 0)
+ status = uint32(r0)
+ return
+}
+
+func rtlNtStatusToDosError(status uint32) (winerr error) {
+ r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
+ if r0 != 0 {
+ winerr = syscall.Errno(r0)
+ }
+ return
+}
+
+func localAlloc(flags uint32, size int) (ptr uintptr) {
+ r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(flags), uintptr(size), 0)
+ ptr = uintptr(r0)
+ return
+}
+
+func localFree(ptr uintptr) {
+ syscall.Syscall(procLocalFree.Addr(), 1, uintptr(ptr), 0, 0)
+ return
+}