Browse code

create a new file networks.go and move network part codes from cluster.go into networks.go

Signed-off-by: allencloud <allen.sun@daocloud.io>

allencloud authored on 2017/02/12 03:49:10
Showing 2 changed files
... ...
@@ -58,7 +58,6 @@ import (
58 58
 	executorpkg "github.com/docker/docker/daemon/cluster/executor"
59 59
 	"github.com/docker/docker/opts"
60 60
 	"github.com/docker/docker/pkg/signal"
61
-	"github.com/docker/docker/runconfig"
62 61
 	swarmapi "github.com/docker/swarmkit/api"
63 62
 	"github.com/docker/swarmkit/manager/encryption"
64 63
 	swarmnode "github.com/docker/swarmkit/node"
... ...
@@ -784,271 +783,6 @@ func (c *Cluster) errNoManager(st nodeState) error {
784 784
 	return errors.New("This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.")
785 785
 }
786 786
 
787
-// GetNetwork returns a cluster network by an ID.
788
-func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, error) {
789
-	c.mu.RLock()
790
-	defer c.mu.RUnlock()
791
-
792
-	state := c.currentNodeState()
793
-	if !state.IsActiveManager() {
794
-		return apitypes.NetworkResource{}, c.errNoManager(state)
795
-	}
796
-
797
-	ctx, cancel := c.getRequestContext()
798
-	defer cancel()
799
-
800
-	network, err := getNetwork(ctx, state.controlClient, input)
801
-	if err != nil {
802
-		return apitypes.NetworkResource{}, err
803
-	}
804
-	return convert.BasicNetworkFromGRPC(*network), nil
805
-}
806
-
807
-func (c *Cluster) getNetworks(filters *swarmapi.ListNetworksRequest_Filters) ([]apitypes.NetworkResource, error) {
808
-	c.mu.RLock()
809
-	defer c.mu.RUnlock()
810
-
811
-	state := c.currentNodeState()
812
-	if !state.IsActiveManager() {
813
-		return nil, c.errNoManager(state)
814
-	}
815
-
816
-	ctx, cancel := c.getRequestContext()
817
-	defer cancel()
818
-
819
-	r, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters})
820
-	if err != nil {
821
-		return nil, err
822
-	}
823
-
824
-	var networks []apitypes.NetworkResource
825
-
826
-	for _, network := range r.Networks {
827
-		networks = append(networks, convert.BasicNetworkFromGRPC(*network))
828
-	}
829
-
830
-	return networks, nil
831
-}
832
-
833
-// GetNetworks returns all current cluster managed networks.
834
-func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
835
-	return c.getNetworks(nil)
836
-}
837
-
838
-// GetNetworksByName returns cluster managed networks by name.
839
-// It is ok to have multiple networks here. #18864
840
-func (c *Cluster) GetNetworksByName(name string) ([]apitypes.NetworkResource, error) {
841
-	// Note that swarmapi.GetNetworkRequest.Name is not functional.
842
-	// So we cannot just use that with c.GetNetwork.
843
-	return c.getNetworks(&swarmapi.ListNetworksRequest_Filters{
844
-		Names: []string{name},
845
-	})
846
-}
847
-
848
-func attacherKey(target, containerID string) string {
849
-	return containerID + ":" + target
850
-}
851
-
852
-// UpdateAttachment signals the attachment config to the attachment
853
-// waiter who is trying to start or attach the container to the
854
-// network.
855
-func (c *Cluster) UpdateAttachment(target, containerID string, config *network.NetworkingConfig) error {
856
-	c.mu.RLock()
857
-	attacher, ok := c.attachers[attacherKey(target, containerID)]
858
-	c.mu.RUnlock()
859
-	if !ok || attacher == nil {
860
-		return fmt.Errorf("could not find attacher for container %s to network %s", containerID, target)
861
-	}
862
-
863
-	attacher.attachWaitCh <- config
864
-	close(attacher.attachWaitCh)
865
-	return nil
866
-}
867
-
868
-// WaitForDetachment waits for the container to stop or detach from
869
-// the network.
870
-func (c *Cluster) WaitForDetachment(ctx context.Context, networkName, networkID, taskID, containerID string) error {
871
-	c.mu.RLock()
872
-	attacher, ok := c.attachers[attacherKey(networkName, containerID)]
873
-	if !ok {
874
-		attacher, ok = c.attachers[attacherKey(networkID, containerID)]
875
-	}
876
-	state := c.currentNodeState()
877
-	if state.swarmNode == nil || state.swarmNode.Agent() == nil {
878
-		c.mu.RUnlock()
879
-		return errors.New("invalid cluster node while waiting for detachment")
880
-	}
881
-
882
-	c.mu.RUnlock()
883
-	agent := state.swarmNode.Agent()
884
-	if ok && attacher != nil &&
885
-		attacher.detachWaitCh != nil &&
886
-		attacher.attachCompleteCh != nil {
887
-		// Attachment may be in progress still so wait for
888
-		// attachment to complete.
889
-		select {
890
-		case <-attacher.attachCompleteCh:
891
-		case <-ctx.Done():
892
-			return ctx.Err()
893
-		}
894
-
895
-		if attacher.taskID == taskID {
896
-			select {
897
-			case <-attacher.detachWaitCh:
898
-			case <-ctx.Done():
899
-				return ctx.Err()
900
-			}
901
-		}
902
-	}
903
-
904
-	return agent.ResourceAllocator().DetachNetwork(ctx, taskID)
905
-}
906
-
907
-// AttachNetwork generates an attachment request towards the manager.
908
-func (c *Cluster) AttachNetwork(target string, containerID string, addresses []string) (*network.NetworkingConfig, error) {
909
-	aKey := attacherKey(target, containerID)
910
-	c.mu.Lock()
911
-	state := c.currentNodeState()
912
-	if state.swarmNode == nil || state.swarmNode.Agent() == nil {
913
-		c.mu.Unlock()
914
-		return nil, errors.New("invalid cluster node while attaching to network")
915
-	}
916
-	if attacher, ok := c.attachers[aKey]; ok {
917
-		c.mu.Unlock()
918
-		return attacher.config, nil
919
-	}
920
-
921
-	agent := state.swarmNode.Agent()
922
-	attachWaitCh := make(chan *network.NetworkingConfig)
923
-	detachWaitCh := make(chan struct{})
924
-	attachCompleteCh := make(chan struct{})
925
-	c.attachers[aKey] = &attacher{
926
-		attachWaitCh:     attachWaitCh,
927
-		attachCompleteCh: attachCompleteCh,
928
-		detachWaitCh:     detachWaitCh,
929
-	}
930
-	c.mu.Unlock()
931
-
932
-	ctx, cancel := c.getRequestContext()
933
-	defer cancel()
934
-
935
-	taskID, err := agent.ResourceAllocator().AttachNetwork(ctx, containerID, target, addresses)
936
-	if err != nil {
937
-		c.mu.Lock()
938
-		delete(c.attachers, aKey)
939
-		c.mu.Unlock()
940
-		return nil, fmt.Errorf("Could not attach to network %s: %v", target, err)
941
-	}
942
-
943
-	c.mu.Lock()
944
-	c.attachers[aKey].taskID = taskID
945
-	close(attachCompleteCh)
946
-	c.mu.Unlock()
947
-
948
-	logrus.Debugf("Successfully attached to network %s with tid %s", target, taskID)
949
-
950
-	var config *network.NetworkingConfig
951
-	select {
952
-	case config = <-attachWaitCh:
953
-	case <-ctx.Done():
954
-		return nil, fmt.Errorf("attaching to network failed, make sure your network options are correct and check manager logs: %v", ctx.Err())
955
-	}
956
-
957
-	c.mu.Lock()
958
-	c.attachers[aKey].config = config
959
-	c.mu.Unlock()
960
-	return config, nil
961
-}
962
-
963
-// DetachNetwork unblocks the waiters waiting on WaitForDetachment so
964
-// that a request to detach can be generated towards the manager.
965
-func (c *Cluster) DetachNetwork(target string, containerID string) error {
966
-	aKey := attacherKey(target, containerID)
967
-
968
-	c.mu.Lock()
969
-	attacher, ok := c.attachers[aKey]
970
-	delete(c.attachers, aKey)
971
-	c.mu.Unlock()
972
-
973
-	if !ok {
974
-		return fmt.Errorf("could not find network attachment for container %s to network %s", containerID, target)
975
-	}
976
-
977
-	close(attacher.detachWaitCh)
978
-	return nil
979
-}
980
-
981
-// CreateNetwork creates a new cluster managed network.
982
-func (c *Cluster) CreateNetwork(s apitypes.NetworkCreateRequest) (string, error) {
983
-	c.mu.RLock()
984
-	defer c.mu.RUnlock()
985
-
986
-	state := c.currentNodeState()
987
-	if !state.IsActiveManager() {
988
-		return "", c.errNoManager(state)
989
-	}
990
-
991
-	if runconfig.IsPreDefinedNetwork(s.Name) {
992
-		err := fmt.Errorf("%s is a pre-defined network and cannot be created", s.Name)
993
-		return "", apierrors.NewRequestForbiddenError(err)
994
-	}
995
-
996
-	ctx, cancel := c.getRequestContext()
997
-	defer cancel()
998
-
999
-	networkSpec := convert.BasicNetworkCreateToGRPC(s)
1000
-	r, err := state.controlClient.CreateNetwork(ctx, &swarmapi.CreateNetworkRequest{Spec: &networkSpec})
1001
-	if err != nil {
1002
-		return "", err
1003
-	}
1004
-
1005
-	return r.Network.ID, nil
1006
-}
1007
-
1008
-// RemoveNetwork removes a cluster network.
1009
-func (c *Cluster) RemoveNetwork(input string) error {
1010
-	c.mu.RLock()
1011
-	defer c.mu.RUnlock()
1012
-
1013
-	state := c.currentNodeState()
1014
-	if !state.IsActiveManager() {
1015
-		return c.errNoManager(state)
1016
-	}
1017
-
1018
-	ctx, cancel := c.getRequestContext()
1019
-	defer cancel()
1020
-
1021
-	network, err := getNetwork(ctx, state.controlClient, input)
1022
-	if err != nil {
1023
-		return err
1024
-	}
1025
-
1026
-	_, err = state.controlClient.RemoveNetwork(ctx, &swarmapi.RemoveNetworkRequest{NetworkID: network.ID})
1027
-	return err
1028
-}
1029
-
1030
-func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.ControlClient, s *types.ServiceSpec) error {
1031
-	// Always prefer NetworkAttachmentConfigs from TaskTemplate
1032
-	// but fallback to service spec for backward compatibility
1033
-	networks := s.TaskTemplate.Networks
1034
-	if len(networks) == 0 {
1035
-		networks = s.Networks
1036
-	}
1037
-
1038
-	for i, n := range networks {
1039
-		apiNetwork, err := getNetwork(ctx, client, n.Target)
1040
-		if err != nil {
1041
-			if ln, _ := c.config.Backend.FindNetwork(n.Target); ln != nil && !ln.Info().Dynamic() {
1042
-				err = fmt.Errorf("The network %s cannot be used with services. Only networks scoped to the swarm can be used, such as those created with the overlay driver.", ln.Name())
1043
-				return apierrors.NewRequestForbiddenError(err)
1044
-			}
1045
-			return err
1046
-		}
1047
-		networks[i].Target = apiNetwork.ID
1048
-	}
1049
-	return nil
1050
-}
1051
-
1052 787
 // Cleanup stops active swarm node. This is run before daemon shutdown.
1053 788
 func (c *Cluster) Cleanup() {
1054 789
 	c.controlMutex.Lock()
1055 790
new file mode 100644
... ...
@@ -0,0 +1,281 @@
0
+package cluster
1
+
2
+import (
3
+	"fmt"
4
+
5
+	"github.com/Sirupsen/logrus"
6
+	apierrors "github.com/docker/docker/api/errors"
7
+	apitypes "github.com/docker/docker/api/types"
8
+	"github.com/docker/docker/api/types/network"
9
+	types "github.com/docker/docker/api/types/swarm"
10
+	"github.com/docker/docker/daemon/cluster/convert"
11
+	"github.com/docker/docker/runconfig"
12
+	swarmapi "github.com/docker/swarmkit/api"
13
+	"github.com/pkg/errors"
14
+	"golang.org/x/net/context"
15
+)
16
+
17
+// GetNetworks returns all current cluster managed networks.
18
+func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
19
+	return c.getNetworks(nil)
20
+}
21
+
22
+func (c *Cluster) getNetworks(filters *swarmapi.ListNetworksRequest_Filters) ([]apitypes.NetworkResource, error) {
23
+	c.mu.RLock()
24
+	defer c.mu.RUnlock()
25
+
26
+	state := c.currentNodeState()
27
+	if !state.IsActiveManager() {
28
+		return nil, c.errNoManager(state)
29
+	}
30
+
31
+	ctx, cancel := c.getRequestContext()
32
+	defer cancel()
33
+
34
+	r, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters})
35
+	if err != nil {
36
+		return nil, err
37
+	}
38
+
39
+	var networks []apitypes.NetworkResource
40
+
41
+	for _, network := range r.Networks {
42
+		networks = append(networks, convert.BasicNetworkFromGRPC(*network))
43
+	}
44
+
45
+	return networks, nil
46
+}
47
+
48
+// GetNetwork returns a cluster network by an ID.
49
+func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, error) {
50
+	c.mu.RLock()
51
+	defer c.mu.RUnlock()
52
+
53
+	state := c.currentNodeState()
54
+	if !state.IsActiveManager() {
55
+		return apitypes.NetworkResource{}, c.errNoManager(state)
56
+	}
57
+
58
+	ctx, cancel := c.getRequestContext()
59
+	defer cancel()
60
+
61
+	network, err := getNetwork(ctx, state.controlClient, input)
62
+	if err != nil {
63
+		return apitypes.NetworkResource{}, err
64
+	}
65
+	return convert.BasicNetworkFromGRPC(*network), nil
66
+}
67
+
68
+// GetNetworksByName returns cluster managed networks by name.
69
+// It is ok to have multiple networks here. #18864
70
+func (c *Cluster) GetNetworksByName(name string) ([]apitypes.NetworkResource, error) {
71
+	// Note that swarmapi.GetNetworkRequest.Name is not functional.
72
+	// So we cannot just use that with c.GetNetwork.
73
+	return c.getNetworks(&swarmapi.ListNetworksRequest_Filters{
74
+		Names: []string{name},
75
+	})
76
+}
77
+
78
+func attacherKey(target, containerID string) string {
79
+	return containerID + ":" + target
80
+}
81
+
82
+// UpdateAttachment signals the attachment config to the attachment
83
+// waiter who is trying to start or attach the container to the
84
+// network.
85
+func (c *Cluster) UpdateAttachment(target, containerID string, config *network.NetworkingConfig) error {
86
+	c.mu.RLock()
87
+	attacher, ok := c.attachers[attacherKey(target, containerID)]
88
+	c.mu.RUnlock()
89
+	if !ok || attacher == nil {
90
+		return fmt.Errorf("could not find attacher for container %s to network %s", containerID, target)
91
+	}
92
+
93
+	attacher.attachWaitCh <- config
94
+	close(attacher.attachWaitCh)
95
+	return nil
96
+}
97
+
98
+// WaitForDetachment waits for the container to stop or detach from
99
+// the network.
100
+func (c *Cluster) WaitForDetachment(ctx context.Context, networkName, networkID, taskID, containerID string) error {
101
+	c.mu.RLock()
102
+	attacher, ok := c.attachers[attacherKey(networkName, containerID)]
103
+	if !ok {
104
+		attacher, ok = c.attachers[attacherKey(networkID, containerID)]
105
+	}
106
+	state := c.currentNodeState()
107
+	if state.swarmNode == nil || state.swarmNode.Agent() == nil {
108
+		c.mu.RUnlock()
109
+		return errors.New("invalid cluster node while waiting for detachment")
110
+	}
111
+
112
+	c.mu.RUnlock()
113
+	agent := state.swarmNode.Agent()
114
+	if ok && attacher != nil &&
115
+		attacher.detachWaitCh != nil &&
116
+		attacher.attachCompleteCh != nil {
117
+		// Attachment may be in progress still so wait for
118
+		// attachment to complete.
119
+		select {
120
+		case <-attacher.attachCompleteCh:
121
+		case <-ctx.Done():
122
+			return ctx.Err()
123
+		}
124
+
125
+		if attacher.taskID == taskID {
126
+			select {
127
+			case <-attacher.detachWaitCh:
128
+			case <-ctx.Done():
129
+				return ctx.Err()
130
+			}
131
+		}
132
+	}
133
+
134
+	return agent.ResourceAllocator().DetachNetwork(ctx, taskID)
135
+}
136
+
137
+// AttachNetwork generates an attachment request towards the manager.
138
+func (c *Cluster) AttachNetwork(target string, containerID string, addresses []string) (*network.NetworkingConfig, error) {
139
+	aKey := attacherKey(target, containerID)
140
+	c.mu.Lock()
141
+	state := c.currentNodeState()
142
+	if state.swarmNode == nil || state.swarmNode.Agent() == nil {
143
+		c.mu.Unlock()
144
+		return nil, errors.New("invalid cluster node while attaching to network")
145
+	}
146
+	if attacher, ok := c.attachers[aKey]; ok {
147
+		c.mu.Unlock()
148
+		return attacher.config, nil
149
+	}
150
+
151
+	agent := state.swarmNode.Agent()
152
+	attachWaitCh := make(chan *network.NetworkingConfig)
153
+	detachWaitCh := make(chan struct{})
154
+	attachCompleteCh := make(chan struct{})
155
+	c.attachers[aKey] = &attacher{
156
+		attachWaitCh:     attachWaitCh,
157
+		attachCompleteCh: attachCompleteCh,
158
+		detachWaitCh:     detachWaitCh,
159
+	}
160
+	c.mu.Unlock()
161
+
162
+	ctx, cancel := c.getRequestContext()
163
+	defer cancel()
164
+
165
+	taskID, err := agent.ResourceAllocator().AttachNetwork(ctx, containerID, target, addresses)
166
+	if err != nil {
167
+		c.mu.Lock()
168
+		delete(c.attachers, aKey)
169
+		c.mu.Unlock()
170
+		return nil, fmt.Errorf("Could not attach to network %s: %v", target, err)
171
+	}
172
+
173
+	c.mu.Lock()
174
+	c.attachers[aKey].taskID = taskID
175
+	close(attachCompleteCh)
176
+	c.mu.Unlock()
177
+
178
+	logrus.Debugf("Successfully attached to network %s with tid %s", target, taskID)
179
+
180
+	var config *network.NetworkingConfig
181
+	select {
182
+	case config = <-attachWaitCh:
183
+	case <-ctx.Done():
184
+		return nil, fmt.Errorf("attaching to network failed, make sure your network options are correct and check manager logs: %v", ctx.Err())
185
+	}
186
+
187
+	c.mu.Lock()
188
+	c.attachers[aKey].config = config
189
+	c.mu.Unlock()
190
+	return config, nil
191
+}
192
+
193
+// DetachNetwork unblocks the waiters waiting on WaitForDetachment so
194
+// that a request to detach can be generated towards the manager.
195
+func (c *Cluster) DetachNetwork(target string, containerID string) error {
196
+	aKey := attacherKey(target, containerID)
197
+
198
+	c.mu.Lock()
199
+	attacher, ok := c.attachers[aKey]
200
+	delete(c.attachers, aKey)
201
+	c.mu.Unlock()
202
+
203
+	if !ok {
204
+		return fmt.Errorf("could not find network attachment for container %s to network %s", containerID, target)
205
+	}
206
+
207
+	close(attacher.detachWaitCh)
208
+	return nil
209
+}
210
+
211
+// CreateNetwork creates a new cluster managed network.
212
+func (c *Cluster) CreateNetwork(s apitypes.NetworkCreateRequest) (string, error) {
213
+	c.mu.RLock()
214
+	defer c.mu.RUnlock()
215
+
216
+	state := c.currentNodeState()
217
+	if !state.IsActiveManager() {
218
+		return "", c.errNoManager(state)
219
+	}
220
+
221
+	if runconfig.IsPreDefinedNetwork(s.Name) {
222
+		err := fmt.Errorf("%s is a pre-defined network and cannot be created", s.Name)
223
+		return "", apierrors.NewRequestForbiddenError(err)
224
+	}
225
+
226
+	ctx, cancel := c.getRequestContext()
227
+	defer cancel()
228
+
229
+	networkSpec := convert.BasicNetworkCreateToGRPC(s)
230
+	r, err := state.controlClient.CreateNetwork(ctx, &swarmapi.CreateNetworkRequest{Spec: &networkSpec})
231
+	if err != nil {
232
+		return "", err
233
+	}
234
+
235
+	return r.Network.ID, nil
236
+}
237
+
238
+// RemoveNetwork removes a cluster network.
239
+func (c *Cluster) RemoveNetwork(input string) error {
240
+	c.mu.RLock()
241
+	defer c.mu.RUnlock()
242
+
243
+	state := c.currentNodeState()
244
+	if !state.IsActiveManager() {
245
+		return c.errNoManager(state)
246
+	}
247
+
248
+	ctx, cancel := c.getRequestContext()
249
+	defer cancel()
250
+
251
+	network, err := getNetwork(ctx, state.controlClient, input)
252
+	if err != nil {
253
+		return err
254
+	}
255
+
256
+	_, err = state.controlClient.RemoveNetwork(ctx, &swarmapi.RemoveNetworkRequest{NetworkID: network.ID})
257
+	return err
258
+}
259
+
260
+func (c *Cluster) populateNetworkID(ctx context.Context, client swarmapi.ControlClient, s *types.ServiceSpec) error {
261
+	// Always prefer NetworkAttachmentConfigs from TaskTemplate
262
+	// but fallback to service spec for backward compatibility
263
+	networks := s.TaskTemplate.Networks
264
+	if len(networks) == 0 {
265
+		networks = s.Networks
266
+	}
267
+
268
+	for i, n := range networks {
269
+		apiNetwork, err := getNetwork(ctx, client, n.Target)
270
+		if err != nil {
271
+			if ln, _ := c.config.Backend.FindNetwork(n.Target); ln != nil && !ln.Info().Dynamic() {
272
+				err = fmt.Errorf("The network %s cannot be used with services. Only networks scoped to the swarm can be used, such as those created with the overlay driver.", ln.Name())
273
+				return apierrors.NewRequestForbiddenError(err)
274
+			}
275
+			return err
276
+		}
277
+		networks[i].Target = apiNetwork.ID
278
+	}
279
+	return nil
280
+}