-
Notifications
You must be signed in to change notification settings - Fork 7
/
client.go
160 lines (123 loc) · 3.83 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package hcs
import (
"fmt"
"time"
"github.com/Microsoft/hcsshim"
)
type Client struct{}
func (c *Client) GetContainers(q hcsshim.ComputeSystemQuery) ([]hcsshim.ContainerProperties, error) {
return hcsshim.GetContainers(q)
}
func (c *Client) NameToGuid(name string) (hcsshim.GUID, error) {
return hcsshim.NameToGuid(name)
}
func (c *Client) GetLayerMountPath(info hcsshim.DriverInfo, id string) (string, error) {
return hcsshim.GetLayerMountPath(info, id)
}
func (c *Client) CreateContainer(id string, config *hcsshim.ContainerConfig) (Container, error) {
return hcsshim.CreateContainer(id, config)
}
func (c *Client) OpenContainer(id string) (Container, error) {
return hcsshim.OpenContainer(id)
}
func (c *Client) IsPending(err error) bool {
return hcsshim.IsPending(err)
}
func (c *Client) GetContainerProperties(id string) (hcsshim.ContainerProperties, error) {
query := hcsshim.ComputeSystemQuery{
IDs: []string{id},
}
cps, err := c.GetContainers(query)
if err != nil {
return hcsshim.ContainerProperties{}, err
}
if len(cps) == 0 {
return hcsshim.ContainerProperties{}, &NotFoundError{Id: id}
}
if len(cps) > 1 {
return hcsshim.ContainerProperties{}, &DuplicateError{Id: id}
}
return cps[0], nil
}
func (c *Client) CreateEndpoint(endpoint *hcsshim.HNSEndpoint) (*hcsshim.HNSEndpoint, error) {
return endpoint.Create()
}
func (c *Client) UpdateEndpoint(endpoint *hcsshim.HNSEndpoint) (*hcsshim.HNSEndpoint, error) {
return endpoint.Update()
}
func (c *Client) DeleteEndpoint(endpoint *hcsshim.HNSEndpoint) (*hcsshim.HNSEndpoint, error) {
return endpoint.Delete()
}
func (c *Client) CreateNetwork(network *hcsshim.HNSNetwork, networkReady func() (bool, error)) (*hcsshim.HNSNetwork, error) {
var net *hcsshim.HNSNetwork
var err error
/*
* This @errElmNotFound error is notorious for being thrown sometimes without any real reason
* (at least we believe so) -- possibly a bug in the Windows container networking stack.
* Let's give it a 2nd chance (and a 3rd) to get it right!
*/
const errElmNotFound = "network create: HNS failed with error : Element not found. "
for i := 0; i < 3 && net == nil; i++ {
net, err = network.Create()
if err != nil && err.Error() != errElmNotFound {
return nil, err
}
}
if err != nil {
return nil, err
}
networkUp := false
for i := 0; i < 10; i++ {
time.Sleep(200 * time.Duration(i) * time.Millisecond)
networkUp, err = networkReady()
if err != nil {
return nil, err
}
if networkUp {
break
}
}
if !networkUp {
return nil, fmt.Errorf("network %s not ready in time", net.Name)
}
return net, nil
}
func (c *Client) DeleteNetwork(network *hcsshim.HNSNetwork) (*hcsshim.HNSNetwork, error) {
return network.Delete()
}
func (c *Client) HNSListNetworkRequest() ([]hcsshim.HNSNetwork, error) {
return hcsshim.HNSListNetworkRequest("GET", "", "")
}
func (c *Client) GetHNSEndpointByID(id string) (*hcsshim.HNSEndpoint, error) {
return hcsshim.GetHNSEndpointByID(id)
}
func (c *Client) GetHNSEndpointByName(name string) (*hcsshim.HNSEndpoint, error) {
return hcsshim.GetHNSEndpointByName(name)
}
func (c *Client) GetHNSNetworkByName(name string) (*hcsshim.HNSNetwork, error) {
return hcsshim.GetHNSNetworkByName(name)
}
func (c *Client) HotAttachEndpoint(containerID string, endpointID string, endpointReady func() (bool, error)) error {
if err := hcsshim.HotAttachEndpoint(containerID, endpointID); err != nil {
return err
}
endpointUp := false
for i := 0; i < 10; i++ {
var err error
endpointUp, err = endpointReady()
if err != nil {
return err
}
if endpointUp {
break
}
time.Sleep(200 * time.Millisecond)
}
if !endpointUp {
return fmt.Errorf("endpoint %s not ready in time", endpointID)
}
return nil
}
func (c *Client) HotDetachEndpoint(containerID string, endpointID string) error {
return hcsshim.HotDetachEndpoint(containerID, endpointID)
}