network.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. package libnetwork
  2. import (
  3. "encoding/json"
  4. "sync"
  5. log "github.com/Sirupsen/logrus"
  6. "github.com/docker/docker/pkg/stringid"
  7. "github.com/docker/libnetwork/datastore"
  8. "github.com/docker/libnetwork/driverapi"
  9. "github.com/docker/libnetwork/netlabel"
  10. "github.com/docker/libnetwork/options"
  11. "github.com/docker/libnetwork/types"
  12. )
  13. // A Network represents a logical connectivity zone that containers may
  14. // join using the Link method. A Network is managed by a specific driver.
  15. type Network interface {
  16. // A user chosen name for this network.
  17. Name() string
  18. // A system generated id for this network.
  19. ID() string
  20. // The type of network, which corresponds to its managing driver.
  21. Type() string
  22. // Create a new endpoint to this network symbolically identified by the
  23. // specified unique name. The options parameter carry driver specific options.
  24. // Labels support will be added in the near future.
  25. CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
  26. // Delete the network.
  27. Delete() error
  28. // Endpoints returns the list of Endpoint(s) in this network.
  29. Endpoints() []Endpoint
  30. // WalkEndpoints uses the provided function to walk the Endpoints
  31. WalkEndpoints(walker EndpointWalker)
  32. // EndpointByName returns the Endpoint which has the passed name. If not found, the error ErrNoSuchEndpoint is returned.
  33. EndpointByName(name string) (Endpoint, error)
  34. // EndpointByID returns the Endpoint which has the passed id. If not found, the error ErrNoSuchEndpoint is returned.
  35. EndpointByID(id string) (Endpoint, error)
  36. }
  37. // EndpointWalker is a client provided function which will be used to walk the Endpoints.
  38. // When the function returns true, the walk will stop.
  39. type EndpointWalker func(ep Endpoint) bool
  40. type network struct {
  41. ctrlr *controller
  42. name string
  43. networkType string
  44. id types.UUID
  45. driver driverapi.Driver
  46. enableIPv6 bool
  47. endpointCnt uint64
  48. endpoints endpointTable
  49. generic options.Generic
  50. dbIndex uint64
  51. sync.Mutex
  52. }
  53. func (n *network) Name() string {
  54. n.Lock()
  55. defer n.Unlock()
  56. return n.name
  57. }
  58. func (n *network) ID() string {
  59. n.Lock()
  60. defer n.Unlock()
  61. return string(n.id)
  62. }
  63. func (n *network) Type() string {
  64. n.Lock()
  65. defer n.Unlock()
  66. if n.driver == nil {
  67. return ""
  68. }
  69. return n.driver.Type()
  70. }
  71. func (n *network) Key() []string {
  72. n.Lock()
  73. defer n.Unlock()
  74. return []string{datastore.NetworkKeyPrefix, string(n.id)}
  75. }
  76. func (n *network) KeyPrefix() []string {
  77. return []string{datastore.NetworkKeyPrefix}
  78. }
  79. func (n *network) Value() []byte {
  80. n.Lock()
  81. defer n.Unlock()
  82. b, err := json.Marshal(n)
  83. if err != nil {
  84. return nil
  85. }
  86. return b
  87. }
  88. func (n *network) Index() uint64 {
  89. n.Lock()
  90. defer n.Unlock()
  91. return n.dbIndex
  92. }
  93. func (n *network) SetIndex(index uint64) {
  94. n.Lock()
  95. n.dbIndex = index
  96. n.Unlock()
  97. }
  98. func (n *network) EndpointCnt() uint64 {
  99. n.Lock()
  100. defer n.Unlock()
  101. return n.endpointCnt
  102. }
  103. func (n *network) IncEndpointCnt() {
  104. n.Lock()
  105. n.endpointCnt++
  106. n.Unlock()
  107. }
  108. func (n *network) DecEndpointCnt() {
  109. n.Lock()
  110. n.endpointCnt--
  111. n.Unlock()
  112. }
  113. // TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
  114. func (n *network) MarshalJSON() ([]byte, error) {
  115. netMap := make(map[string]interface{})
  116. netMap["name"] = n.name
  117. netMap["id"] = string(n.id)
  118. netMap["networkType"] = n.networkType
  119. netMap["endpointCnt"] = n.endpointCnt
  120. netMap["enableIPv6"] = n.enableIPv6
  121. netMap["generic"] = n.generic
  122. return json.Marshal(netMap)
  123. }
  124. // TODO : Can be made much more generic with the help of reflection (but has some golang limitations)
  125. func (n *network) UnmarshalJSON(b []byte) (err error) {
  126. var netMap map[string]interface{}
  127. if err := json.Unmarshal(b, &netMap); err != nil {
  128. return err
  129. }
  130. n.name = netMap["name"].(string)
  131. n.id = types.UUID(netMap["id"].(string))
  132. n.networkType = netMap["networkType"].(string)
  133. n.endpointCnt = uint64(netMap["endpointCnt"].(float64))
  134. n.enableIPv6 = netMap["enableIPv6"].(bool)
  135. if netMap["generic"] != nil {
  136. n.generic = netMap["generic"].(map[string]interface{})
  137. }
  138. return nil
  139. }
  140. // NetworkOption is a option setter function type used to pass varios options to
  141. // NewNetwork method. The various setter functions of type NetworkOption are
  142. // provided by libnetwork, they look like NetworkOptionXXXX(...)
  143. type NetworkOption func(n *network)
  144. // NetworkOptionGeneric function returns an option setter for a Generic option defined
  145. // in a Dictionary of Key-Value pair
  146. func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption {
  147. return func(n *network) {
  148. n.generic = generic
  149. if _, ok := generic[netlabel.EnableIPv6]; ok {
  150. n.enableIPv6 = generic[netlabel.EnableIPv6].(bool)
  151. }
  152. }
  153. }
  154. func (n *network) processOptions(options ...NetworkOption) {
  155. for _, opt := range options {
  156. if opt != nil {
  157. opt(n)
  158. }
  159. }
  160. }
  161. func (n *network) Delete() error {
  162. var err error
  163. n.Lock()
  164. ctrlr := n.ctrlr
  165. n.Unlock()
  166. ctrlr.Lock()
  167. _, ok := ctrlr.networks[n.id]
  168. ctrlr.Unlock()
  169. if !ok {
  170. return &UnknownNetworkError{name: n.name, id: string(n.id)}
  171. }
  172. numEps := n.EndpointCnt()
  173. if numEps != 0 {
  174. return &ActiveEndpointsError{name: n.name, id: string(n.id)}
  175. }
  176. // deleteNetworkFromStore performs an atomic delete operation and the network.endpointCnt field will help
  177. // prevent any possible race between endpoint join and network delete
  178. if err = ctrlr.deleteNetworkFromStore(n); err != nil {
  179. if err == datastore.ErrKeyModified {
  180. return types.InternalErrorf("operation in progress. delete failed for network %s. Please try again.")
  181. }
  182. return err
  183. }
  184. if err = n.deleteNetwork(); err != nil {
  185. return err
  186. }
  187. return nil
  188. }
  189. func (n *network) deleteNetwork() error {
  190. n.Lock()
  191. id := n.id
  192. d := n.driver
  193. n.ctrlr.Lock()
  194. delete(n.ctrlr.networks, id)
  195. n.ctrlr.Unlock()
  196. n.Unlock()
  197. if err := d.DeleteNetwork(n.id); err != nil {
  198. // Forbidden Errors should be honored
  199. if _, ok := err.(types.ForbiddenError); ok {
  200. n.ctrlr.Lock()
  201. n.ctrlr.networks[n.id] = n
  202. n.ctrlr.Unlock()
  203. return err
  204. }
  205. log.Warnf("driver error deleting network %s : %v", n.name, err)
  206. }
  207. return nil
  208. }
  209. func (n *network) addEndpoint(ep *endpoint) error {
  210. var err error
  211. n.Lock()
  212. n.endpoints[ep.id] = ep
  213. d := n.driver
  214. n.Unlock()
  215. defer func() {
  216. if err != nil {
  217. n.Lock()
  218. delete(n.endpoints, ep.id)
  219. n.Unlock()
  220. }
  221. }()
  222. err = d.CreateEndpoint(n.id, ep.id, ep, ep.generic)
  223. if err != nil {
  224. return err
  225. }
  226. return nil
  227. }
  228. func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
  229. var err error
  230. if name == "" {
  231. return nil, ErrInvalidName(name)
  232. }
  233. if _, err = n.EndpointByName(name); err == nil {
  234. return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name)
  235. }
  236. ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})}
  237. ep.id = types.UUID(stringid.GenerateRandomID())
  238. ep.network = n
  239. ep.processOptions(options...)
  240. n.Lock()
  241. ctrlr := n.ctrlr
  242. n.Unlock()
  243. n.IncEndpointCnt()
  244. if err = ctrlr.updateNetworkToStore(n); err != nil {
  245. return nil, err
  246. }
  247. defer func() {
  248. if err != nil {
  249. n.DecEndpointCnt()
  250. if err = ctrlr.updateNetworkToStore(n); err != nil {
  251. log.Warnf("endpoint count cleanup failed when updating network for %s : %v", name, err)
  252. }
  253. }
  254. }()
  255. if err = n.addEndpoint(ep); err != nil {
  256. return nil, err
  257. }
  258. defer func() {
  259. if err != nil {
  260. if e := ep.Delete(); ep != nil {
  261. log.Warnf("cleaning up endpoint failed %s : %v", name, e)
  262. }
  263. }
  264. }()
  265. if err = ctrlr.updateEndpointToStore(ep); err != nil {
  266. return nil, err
  267. }
  268. return ep, nil
  269. }
  270. func (n *network) Endpoints() []Endpoint {
  271. n.Lock()
  272. defer n.Unlock()
  273. list := make([]Endpoint, 0, len(n.endpoints))
  274. for _, e := range n.endpoints {
  275. list = append(list, e)
  276. }
  277. return list
  278. }
  279. func (n *network) WalkEndpoints(walker EndpointWalker) {
  280. for _, e := range n.Endpoints() {
  281. if walker(e) {
  282. return
  283. }
  284. }
  285. }
  286. func (n *network) EndpointByName(name string) (Endpoint, error) {
  287. if name == "" {
  288. return nil, ErrInvalidName(name)
  289. }
  290. var e Endpoint
  291. s := func(current Endpoint) bool {
  292. if current.Name() == name {
  293. e = current
  294. return true
  295. }
  296. return false
  297. }
  298. n.WalkEndpoints(s)
  299. if e == nil {
  300. return nil, ErrNoSuchEndpoint(name)
  301. }
  302. return e, nil
  303. }
  304. func (n *network) EndpointByID(id string) (Endpoint, error) {
  305. if id == "" {
  306. return nil, ErrInvalidID(id)
  307. }
  308. n.Lock()
  309. defer n.Unlock()
  310. if e, ok := n.endpoints[types.UUID(id)]; ok {
  311. return e, nil
  312. }
  313. return nil, ErrNoSuchEndpoint(id)
  314. }
  315. func (n *network) isGlobalScoped() (bool, error) {
  316. n.Lock()
  317. c := n.ctrlr
  318. n.Unlock()
  319. return c.isDriverGlobalScoped(n.networkType)
  320. }