Signed-off-by: John Howard <jhoward@microsoft.com>
| ... | ... |
@@ -1,6 +1,6 @@ |
| 1 | 1 |
# the following lines are in sorted order, FYI |
| 2 | 2 |
github.com/Azure/go-ansiterm 19f72df4d05d31cbe1c56bfc8045c96babff6c7e |
| 3 |
-github.com/Microsoft/hcsshim v0.6.1 |
|
| 3 |
+github.com/Microsoft/hcsshim v0.6.2 |
|
| 4 | 4 |
github.com/Microsoft/go-winio v0.4.4 |
| 5 | 5 |
github.com/moby/buildkit da2b9dc7dab99e824b2b1067ad7d0523e32dd2d9 https://github.com/dmcgowan/buildkit.git |
| 6 | 6 |
github.com/davecgh/go-spew 346938d642f2ec3594ed81d874461961cd0faa76 |
| ... | ... |
@@ -26,6 +26,31 @@ type HNSEndpoint struct {
|
| 26 | 26 |
IsRemoteEndpoint bool `json:",omitempty"` |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
+//SystemType represents the type of the system on which actions are done |
|
| 30 |
+type SystemType string |
|
| 31 |
+ |
|
| 32 |
+// SystemType const |
|
| 33 |
+const ( |
|
| 34 |
+ ContainerType SystemType = "Container" |
|
| 35 |
+ VirtualMachineType SystemType = "VirtualMachine" |
|
| 36 |
+ HostType SystemType = "Host" |
|
| 37 |
+) |
|
| 38 |
+ |
|
| 39 |
+// EndpointAttachDetachRequest is the structure used to send request to the container to modify the system |
|
| 40 |
+// Supported resource types are Network and Request Types are Add/Remove |
|
| 41 |
+type EndpointAttachDetachRequest struct {
|
|
| 42 |
+ ContainerID string `json:"ContainerId,omitempty"` |
|
| 43 |
+ SystemType SystemType `json:"SystemType"` |
|
| 44 |
+ CompartmentID uint16 `json:"CompartmentId,omitempty"` |
|
| 45 |
+ VirtualNICName string `json:"VirtualNicName,omitempty"` |
|
| 46 |
+} |
|
| 47 |
+ |
|
| 48 |
+// EndpointResquestResponse is object to get the endpoint request response |
|
| 49 |
+type EndpointResquestResponse struct {
|
|
| 50 |
+ Success bool |
|
| 51 |
+ Error string |
|
| 52 |
+} |
|
| 53 |
+ |
|
| 29 | 54 |
// HNSEndpointRequest makes a HNS call to modify/query a network endpoint |
| 30 | 55 |
func HNSEndpointRequest(method, path, request string) (*HNSEndpoint, error) {
|
| 31 | 56 |
endpoint := &HNSEndpoint{}
|
| ... | ... |
@@ -94,12 +119,12 @@ func modifyNetworkEndpoint(containerID string, endpointID string, request Reques |
| 94 | 94 |
return nil |
| 95 | 95 |
} |
| 96 | 96 |
|
| 97 |
-// GetHNSEndpointByID |
|
| 97 |
+// GetHNSEndpointByID get the Endpoint by ID |
|
| 98 | 98 |
func GetHNSEndpointByID(endpointID string) (*HNSEndpoint, error) {
|
| 99 | 99 |
return HNSEndpointRequest("GET", endpointID, "")
|
| 100 | 100 |
} |
| 101 | 101 |
|
| 102 |
-// GetHNSNetworkName filtered by Name |
|
| 102 |
+// GetHNSEndpointByName gets the endpoint filtered by Name |
|
| 103 | 103 |
func GetHNSEndpointByName(endpointName string) (*HNSEndpoint, error) {
|
| 104 | 104 |
hnsResponse, err := HNSListEndpointRequest() |
| 105 | 105 |
if err != nil {
|
| ... | ... |
@@ -135,7 +160,7 @@ func (endpoint *HNSEndpoint) Delete() (*HNSEndpoint, error) {
|
| 135 | 135 |
return HNSEndpointRequest("DELETE", endpoint.Id, "")
|
| 136 | 136 |
} |
| 137 | 137 |
|
| 138 |
-// Delete Endpoint by sending EndpointRequest to HNS |
|
| 138 |
+// Update Endpoint |
|
| 139 | 139 |
func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
|
| 140 | 140 |
operation := "Update" |
| 141 | 141 |
title := "HCSShim::HNSEndpoint::" + operation |
| ... | ... |
@@ -144,30 +169,30 @@ func (endpoint *HNSEndpoint) Update() (*HNSEndpoint, error) {
|
| 144 | 144 |
if err != nil {
|
| 145 | 145 |
return nil, err |
| 146 | 146 |
} |
| 147 |
- err = hnsCall("POST", "/endpoints/"+endpoint.Id+"/update", string(jsonString), &endpoint)
|
|
| 147 |
+ err = hnsCall("POST", "/endpoints/"+endpoint.Id, string(jsonString), &endpoint)
|
|
| 148 | 148 |
|
| 149 | 149 |
return endpoint, err |
| 150 | 150 |
} |
| 151 | 151 |
|
| 152 |
-// Hot Attach an endpoint to a container |
|
| 153 |
-func (endpoint *HNSEndpoint) HotAttach(containerID string) error {
|
|
| 154 |
- operation := "HotAttach" |
|
| 152 |
+// ContainerHotAttach attaches an endpoint to a running container |
|
| 153 |
+func (endpoint *HNSEndpoint) ContainerHotAttach(containerID string) error {
|
|
| 154 |
+ operation := "ContainerHotAttach" |
|
| 155 | 155 |
title := "HCSShim::HNSEndpoint::" + operation |
| 156 | 156 |
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID) |
| 157 | 157 |
|
| 158 | 158 |
return modifyNetworkEndpoint(containerID, endpoint.Id, Add) |
| 159 | 159 |
} |
| 160 | 160 |
|
| 161 |
-// Hot Detach an endpoint from a container |
|
| 162 |
-func (endpoint *HNSEndpoint) HotDetach(containerID string) error {
|
|
| 163 |
- operation := "HotDetach" |
|
| 161 |
+// ContainerHotDetach detaches an endpoint from a running container |
|
| 162 |
+func (endpoint *HNSEndpoint) ContainerHotDetach(containerID string) error {
|
|
| 163 |
+ operation := "ContainerHotDetach" |
|
| 164 | 164 |
title := "HCSShim::HNSEndpoint::" + operation |
| 165 | 165 |
logrus.Debugf(title+" id=%s, containerId=%s", endpoint.Id, containerID) |
| 166 | 166 |
|
| 167 | 167 |
return modifyNetworkEndpoint(containerID, endpoint.Id, Remove) |
| 168 | 168 |
} |
| 169 | 169 |
|
| 170 |
-// Apply Acl Policy on the Endpoint |
|
| 170 |
+// ApplyACLPolicy applies Acl Policy on the Endpoint |
|
| 171 | 171 |
func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {
|
| 172 | 172 |
operation := "ApplyACLPolicy" |
| 173 | 173 |
title := "HCSShim::HNSEndpoint::" + operation |
| ... | ... |
@@ -181,3 +206,113 @@ func (endpoint *HNSEndpoint) ApplyACLPolicy(policy *ACLPolicy) error {
|
| 181 | 181 |
_, err = endpoint.Update() |
| 182 | 182 |
return err |
| 183 | 183 |
} |
| 184 |
+ |
|
| 185 |
+// ContainerAttach attaches an endpoint to container |
|
| 186 |
+func (endpoint *HNSEndpoint) ContainerAttach(containerID string, compartmentID uint16) error {
|
|
| 187 |
+ operation := "ContainerAttach" |
|
| 188 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 189 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 190 |
+ |
|
| 191 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 192 |
+ ContainerID: containerID, |
|
| 193 |
+ CompartmentID: compartmentID, |
|
| 194 |
+ SystemType: ContainerType, |
|
| 195 |
+ } |
|
| 196 |
+ response := &EndpointResquestResponse{}
|
|
| 197 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 198 |
+ if err != nil {
|
|
| 199 |
+ return err |
|
| 200 |
+ } |
|
| 201 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
|
|
| 202 |
+} |
|
| 203 |
+ |
|
| 204 |
+// ContainerDetach detaches an endpoint from container |
|
| 205 |
+func (endpoint *HNSEndpoint) ContainerDetach(containerID string) error {
|
|
| 206 |
+ operation := "ContainerDetach" |
|
| 207 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 208 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 209 |
+ |
|
| 210 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 211 |
+ ContainerID: containerID, |
|
| 212 |
+ SystemType: ContainerType, |
|
| 213 |
+ } |
|
| 214 |
+ response := &EndpointResquestResponse{}
|
|
| 215 |
+ |
|
| 216 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 217 |
+ if err != nil {
|
|
| 218 |
+ return err |
|
| 219 |
+ } |
|
| 220 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
|
|
| 221 |
+} |
|
| 222 |
+ |
|
| 223 |
+// HostAttach attaches a nic on the host |
|
| 224 |
+func (endpoint *HNSEndpoint) HostAttach(compartmentID uint16) error {
|
|
| 225 |
+ operation := "HostAttach" |
|
| 226 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 227 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 228 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 229 |
+ CompartmentID: compartmentID, |
|
| 230 |
+ SystemType: HostType, |
|
| 231 |
+ } |
|
| 232 |
+ response := &EndpointResquestResponse{}
|
|
| 233 |
+ |
|
| 234 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 235 |
+ if err != nil {
|
|
| 236 |
+ return err |
|
| 237 |
+ } |
|
| 238 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
|
|
| 239 |
+ |
|
| 240 |
+} |
|
| 241 |
+ |
|
| 242 |
+// HostDetach detaches a nic on the host |
|
| 243 |
+func (endpoint *HNSEndpoint) HostDetach() error {
|
|
| 244 |
+ operation := "HostDetach" |
|
| 245 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 246 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 247 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 248 |
+ SystemType: HostType, |
|
| 249 |
+ } |
|
| 250 |
+ response := &EndpointResquestResponse{}
|
|
| 251 |
+ |
|
| 252 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 253 |
+ if err != nil {
|
|
| 254 |
+ return err |
|
| 255 |
+ } |
|
| 256 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
|
|
| 257 |
+} |
|
| 258 |
+ |
|
| 259 |
+// VirtualMachineNICAttach attaches a endpoint to a virtual machine |
|
| 260 |
+func (endpoint *HNSEndpoint) VirtualMachineNICAttach(virtualMachineNICName string) error {
|
|
| 261 |
+ operation := "VirtualMachineNicAttach" |
|
| 262 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 263 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 264 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 265 |
+ VirtualNICName: virtualMachineNICName, |
|
| 266 |
+ SystemType: VirtualMachineType, |
|
| 267 |
+ } |
|
| 268 |
+ response := &EndpointResquestResponse{}
|
|
| 269 |
+ |
|
| 270 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 271 |
+ if err != nil {
|
|
| 272 |
+ return err |
|
| 273 |
+ } |
|
| 274 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/attach", string(jsonString), &response)
|
|
| 275 |
+} |
|
| 276 |
+ |
|
| 277 |
+// VirtualMachineNICDetach detaches a endpoint from a virtual machine |
|
| 278 |
+func (endpoint *HNSEndpoint) VirtualMachineNICDetach() error {
|
|
| 279 |
+ operation := "VirtualMachineNicDetach" |
|
| 280 |
+ title := "HCSShim::HNSEndpoint::" + operation |
|
| 281 |
+ logrus.Debugf(title+" id=%s", endpoint.Id) |
|
| 282 |
+ |
|
| 283 |
+ requestMessage := &EndpointAttachDetachRequest{
|
|
| 284 |
+ SystemType: VirtualMachineType, |
|
| 285 |
+ } |
|
| 286 |
+ response := &EndpointResquestResponse{}
|
|
| 287 |
+ |
|
| 288 |
+ jsonString, err := json.Marshal(requestMessage) |
|
| 289 |
+ if err != nil {
|
|
| 290 |
+ return err |
|
| 291 |
+ } |
|
| 292 |
+ return hnsCall("POST", "/endpoints/"+endpoint.Id+"/detach", string(jsonString), &response)
|
|
| 293 |
+} |
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
"github.com/sirupsen/logrus" |
| 7 | 7 |
) |
| 8 | 8 |
|
| 9 |
+// RoutePolicy is a structure defining schema for Route based Policy |
|
| 9 | 10 |
type RoutePolicy struct {
|
| 10 | 11 |
Policy |
| 11 | 12 |
DestinationPrefix string `json:"DestinationPrefix,omitempty"` |
| ... | ... |
@@ -13,6 +14,7 @@ type RoutePolicy struct {
|
| 13 | 13 |
EncapEnabled bool `json:"NeedEncap,omitempty"` |
| 14 | 14 |
} |
| 15 | 15 |
|
| 16 |
+// ELBPolicy is a structure defining schema for ELB LoadBalancing based Policy |
|
| 16 | 17 |
type ELBPolicy struct {
|
| 17 | 18 |
LBPolicy |
| 18 | 19 |
SourceVIP string `json:"SourceVIP,omitempty"` |
| ... | ... |
@@ -20,6 +22,7 @@ type ELBPolicy struct {
|
| 20 | 20 |
ILB bool `json:"ILB,omitempty"` |
| 21 | 21 |
} |
| 22 | 22 |
|
| 23 |
+// LBPolicy is a structure defining schema for LoadBalancing based Policy |
|
| 23 | 24 |
type LBPolicy struct {
|
| 24 | 25 |
Policy |
| 25 | 26 |
Protocol uint16 `json:"Protocol,omitempty"` |
| ... | ... |
@@ -27,10 +30,11 @@ type LBPolicy struct {
|
| 27 | 27 |
ExternalPort uint16 |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
+// PolicyList is a structure defining schema for Policy list request |
|
| 30 | 31 |
type PolicyList struct {
|
| 31 |
- Id string `json:"ID,omitempty"` |
|
| 32 |
- EndpointReferences []string `json:"References,omitempty"` |
|
| 33 |
- Policies []string `json:"Policies,omitempty"` |
|
| 32 |
+ ID string `json:"ID,omitempty"` |
|
| 33 |
+ EndpointReferences []string `json:"References,omitempty"` |
|
| 34 |
+ Policies []json.RawMessage `json:"Policies,omitempty"` |
|
| 34 | 35 |
} |
| 35 | 36 |
|
| 36 | 37 |
// HNSPolicyListRequest makes a call into HNS to update/query a single network |
| ... | ... |
@@ -44,6 +48,7 @@ func HNSPolicyListRequest(method, path, request string) (*PolicyList, error) {
|
| 44 | 44 |
return &policy, nil |
| 45 | 45 |
} |
| 46 | 46 |
|
| 47 |
+// HNSListPolicyListRequest gets all the policy list |
|
| 47 | 48 |
func HNSListPolicyListRequest() ([]PolicyList, error) {
|
| 48 | 49 |
var plist []PolicyList |
| 49 | 50 |
err := hnsCall("GET", "/policylists/", "", &plist)
|
| ... | ... |
@@ -54,7 +59,7 @@ func HNSListPolicyListRequest() ([]PolicyList, error) {
|
| 54 | 54 |
return plist, nil |
| 55 | 55 |
} |
| 56 | 56 |
|
| 57 |
-// PolicyListRequest makes a HNS call to modify/query a network endpoint |
|
| 57 |
+// PolicyListRequest makes a HNS call to modify/query a network policy list |
|
| 58 | 58 |
func PolicyListRequest(method, path, request string) (*PolicyList, error) {
|
| 59 | 59 |
policylist := &PolicyList{}
|
| 60 | 60 |
err := hnsCall(method, "/policylists/"+path, request, &policylist) |
| ... | ... |
@@ -65,11 +70,16 @@ func PolicyListRequest(method, path, request string) (*PolicyList, error) {
|
| 65 | 65 |
return policylist, nil |
| 66 | 66 |
} |
| 67 | 67 |
|
| 68 |
+// GetPolicyListByID get the policy list by ID |
|
| 69 |
+func GetPolicyListByID(policyListID string) (*PolicyList, error) {
|
|
| 70 |
+ return PolicyListRequest("GET", policyListID, "")
|
|
| 71 |
+} |
|
| 72 |
+ |
|
| 68 | 73 |
// Create PolicyList by sending PolicyListRequest to HNS. |
| 69 | 74 |
func (policylist *PolicyList) Create() (*PolicyList, error) {
|
| 70 | 75 |
operation := "Create" |
| 71 | 76 |
title := "HCSShim::PolicyList::" + operation |
| 72 |
- logrus.Debugf(title+" id=%s", policylist.Id) |
|
| 77 |
+ logrus.Debugf(title+" id=%s", policylist.ID) |
|
| 73 | 78 |
jsonString, err := json.Marshal(policylist) |
| 74 | 79 |
if err != nil {
|
| 75 | 80 |
return nil, err |
| ... | ... |
@@ -77,20 +87,20 @@ func (policylist *PolicyList) Create() (*PolicyList, error) {
|
| 77 | 77 |
return PolicyListRequest("POST", "", string(jsonString))
|
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 |
-// Create PolicyList by sending PolicyListRequest to HNS |
|
| 80 |
+// Delete deletes PolicyList |
|
| 81 | 81 |
func (policylist *PolicyList) Delete() (*PolicyList, error) {
|
| 82 | 82 |
operation := "Delete" |
| 83 | 83 |
title := "HCSShim::PolicyList::" + operation |
| 84 |
- logrus.Debugf(title+" id=%s", policylist.Id) |
|
| 84 |
+ logrus.Debugf(title+" id=%s", policylist.ID) |
|
| 85 | 85 |
|
| 86 |
- return PolicyListRequest("DELETE", policylist.Id, "")
|
|
| 86 |
+ return PolicyListRequest("DELETE", policylist.ID, "")
|
|
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
-// Add an endpoint to a Policy List |
|
| 89 |
+// AddEndpoint add an endpoint to a Policy List |
|
| 90 | 90 |
func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
|
| 91 | 91 |
operation := "AddEndpoint" |
| 92 | 92 |
title := "HCSShim::PolicyList::" + operation |
| 93 |
- logrus.Debugf(title+" id=%s, endpointId:%s", policylist.Id, endpoint.Id) |
|
| 93 |
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id) |
|
| 94 | 94 |
|
| 95 | 95 |
_, err := policylist.Delete() |
| 96 | 96 |
if err != nil {
|
| ... | ... |
@@ -103,11 +113,11 @@ func (policylist *PolicyList) AddEndpoint(endpoint *HNSEndpoint) (*PolicyList, e |
| 103 | 103 |
return policylist.Create() |
| 104 | 104 |
} |
| 105 | 105 |
|
| 106 |
-// Remove an endpoint from the Policy List |
|
| 106 |
+// RemoveEndpoint removes an endpoint from the Policy List |
|
| 107 | 107 |
func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList, error) {
|
| 108 | 108 |
operation := "RemoveEndpoint" |
| 109 | 109 |
title := "HCSShim::PolicyList::" + operation |
| 110 |
- logrus.Debugf(title+" id=%s, endpointId:%s", policylist.Id, endpoint.Id) |
|
| 110 |
+ logrus.Debugf(title+" id=%s, endpointId:%s", policylist.ID, endpoint.Id) |
|
| 111 | 111 |
|
| 112 | 112 |
_, err := policylist.Delete() |
| 113 | 113 |
if err != nil {
|
| ... | ... |
@@ -153,12 +163,11 @@ func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, vip string, protocol u |
| 153 | 153 |
if err != nil {
|
| 154 | 154 |
return nil, err |
| 155 | 155 |
} |
| 156 |
- |
|
| 157 |
- policylist.Policies[0] = string(jsonString) |
|
| 156 |
+ policylist.Policies = append(policylist.Policies, jsonString) |
|
| 158 | 157 |
return policylist.Create() |
| 159 | 158 |
} |
| 160 | 159 |
|
| 161 |
-// AddLoadBalancer policy list for the specified endpoints |
|
| 160 |
+// AddRoute adds route policy list for the specified endpoints |
|
| 162 | 161 |
func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, encapEnabled bool) (*PolicyList, error) {
|
| 163 | 162 |
operation := "AddRoute" |
| 164 | 163 |
title := "HCSShim::PolicyList::" + operation |
| ... | ... |
@@ -182,6 +191,6 @@ func AddRoute(endpoints []HNSEndpoint, destinationPrefix string, nextHop string, |
| 182 | 182 |
return nil, err |
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 |
- policylist.Policies[0] = string(jsonString) |
|
| 185 |
+ policylist.Policies = append(policylist.Policies, jsonString) |
|
| 186 | 186 |
return policylist.Create() |
| 187 | 187 |
} |
| ... | ... |
@@ -48,6 +48,8 @@ type HvRuntime struct {
|
| 48 | 48 |
LinuxInitrdFile string `json:",omitempty"` // File under ImagePath on host containing an initrd image for starting a Linux utility VM |
| 49 | 49 |
LinuxKernelFile string `json:",omitempty"` // File under ImagePath on host containing a kernel for starting a Linux utility VM |
| 50 | 50 |
LinuxBootParameters string `json:",omitempty"` // Additional boot parameters for starting a Linux Utility VM in initrd mode |
| 51 |
+ BootSource string `json:",omitempty"` // "Vhd" for Linux Utility VM booting from VHD |
|
| 52 |
+ WritableBootSource bool `json:",omitempty"` // Linux Utility VM booting from VHD |
|
| 51 | 53 |
} |
| 52 | 54 |
|
| 53 | 55 |
type MappedVirtualDisk struct {
|
| ... | ... |
@@ -307,6 +307,16 @@ func (r *legacyLayerReader) Read(b []byte) (int, error) {
|
| 307 | 307 |
return r.backupReader.Read(b) |
| 308 | 308 |
} |
| 309 | 309 |
|
| 310 |
+func (r *legacyLayerReader) Seek(offset int64, whence int) (int64, error) {
|
|
| 311 |
+ if r.backupReader == nil {
|
|
| 312 |
+ if r.currentFile == nil {
|
|
| 313 |
+ return 0, errors.New("no current file")
|
|
| 314 |
+ } |
|
| 315 |
+ return r.currentFile.Seek(offset, whence) |
|
| 316 |
+ } |
|
| 317 |
+ return 0, errors.New("seek not supported on this stream")
|
|
| 318 |
+} |
|
| 319 |
+ |
|
| 310 | 320 |
func (r *legacyLayerReader) Close() error {
|
| 311 | 321 |
r.proceed <- false |
| 312 | 322 |
<-r.result |