network.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package libnetwork
  2. import (
  3. "sync"
  4. "github.com/docker/docker/pkg/stringid"
  5. "github.com/docker/libnetwork/driverapi"
  6. "github.com/docker/libnetwork/netlabel"
  7. "github.com/docker/libnetwork/options"
  8. "github.com/docker/libnetwork/types"
  9. )
  10. // A Network represents a logical connectivity zone that containers may
  11. // join using the Link method. A Network is managed by a specific driver.
  12. type Network interface {
  13. // A user chosen name for this network.
  14. Name() string
  15. // A system generated id for this network.
  16. ID() string
  17. // The type of network, which corresponds to its managing driver.
  18. Type() string
  19. // Create a new endpoint to this network symbolically identified by the
  20. // specified unique name. The options parameter carry driver specific options.
  21. // Labels support will be added in the near future.
  22. CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
  23. // Delete the network.
  24. Delete() error
  25. // Endpoints returns the list of Endpoint(s) in this network.
  26. Endpoints() []Endpoint
  27. // WalkEndpoints uses the provided function to walk the Endpoints
  28. WalkEndpoints(walker EndpointWalker)
  29. // EndpointByName returns the Endpoint which has the passed name. If not found, the error ErrNoSuchEndpoint is returned.
  30. EndpointByName(name string) (Endpoint, error)
  31. // EndpointByID returns the Endpoint which has the passed id. If not found, the error ErrNoSuchEndpoint is returned.
  32. EndpointByID(id string) (Endpoint, error)
  33. }
  34. // EndpointWalker is a client provided function which will be used to walk the Endpoints.
  35. // When the function returns true, the walk will stop.
  36. type EndpointWalker func(ep Endpoint) bool
  37. type network struct {
  38. ctrlr *controller
  39. name string
  40. networkType string
  41. id types.UUID
  42. driver driverapi.Driver
  43. enableIPv6 bool
  44. endpoints endpointTable
  45. generic options.Generic
  46. sync.Mutex
  47. }
  48. func (n *network) Name() string {
  49. return n.name
  50. }
  51. func (n *network) ID() string {
  52. return string(n.id)
  53. }
  54. func (n *network) Type() string {
  55. if n.driver == nil {
  56. return ""
  57. }
  58. return n.driver.Type()
  59. }
  60. // NetworkOption is a option setter function type used to pass varios options to
  61. // NewNetwork method. The various setter functions of type NetworkOption are
  62. // provided by libnetwork, they look like NetworkOptionXXXX(...)
  63. type NetworkOption func(n *network)
  64. // NetworkOptionGeneric function returns an option setter for a Generic option defined
  65. // in a Dictionary of Key-Value pair
  66. func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption {
  67. return func(n *network) {
  68. n.generic = generic
  69. if _, ok := generic[netlabel.EnableIPv6]; ok {
  70. n.enableIPv6 = generic[netlabel.EnableIPv6].(bool)
  71. }
  72. }
  73. }
  74. func (n *network) processOptions(options ...NetworkOption) {
  75. for _, opt := range options {
  76. if opt != nil {
  77. opt(n)
  78. }
  79. }
  80. }
  81. func (n *network) Delete() error {
  82. var err error
  83. n.ctrlr.Lock()
  84. _, ok := n.ctrlr.networks[n.id]
  85. if !ok {
  86. n.ctrlr.Unlock()
  87. return &UnknownNetworkError{name: n.name, id: string(n.id)}
  88. }
  89. n.Lock()
  90. numEps := len(n.endpoints)
  91. n.Unlock()
  92. if numEps != 0 {
  93. n.ctrlr.Unlock()
  94. return &ActiveEndpointsError{name: n.name, id: string(n.id)}
  95. }
  96. delete(n.ctrlr.networks, n.id)
  97. n.ctrlr.Unlock()
  98. defer func() {
  99. if err != nil {
  100. n.ctrlr.Lock()
  101. n.ctrlr.networks[n.id] = n
  102. n.ctrlr.Unlock()
  103. }
  104. }()
  105. err = n.driver.DeleteNetwork(n.id)
  106. return err
  107. }
  108. func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
  109. if name == "" {
  110. return nil, ErrInvalidName(name)
  111. }
  112. ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})}
  113. ep.id = types.UUID(stringid.GenerateRandomID())
  114. ep.network = n
  115. ep.processOptions(options...)
  116. d := n.driver
  117. err := d.CreateEndpoint(n.id, ep.id, ep, ep.generic)
  118. if err != nil {
  119. return nil, err
  120. }
  121. n.Lock()
  122. n.endpoints[ep.id] = ep
  123. n.Unlock()
  124. return ep, nil
  125. }
  126. func (n *network) Endpoints() []Endpoint {
  127. n.Lock()
  128. defer n.Unlock()
  129. list := make([]Endpoint, 0, len(n.endpoints))
  130. for _, e := range n.endpoints {
  131. list = append(list, e)
  132. }
  133. return list
  134. }
  135. func (n *network) WalkEndpoints(walker EndpointWalker) {
  136. for _, e := range n.Endpoints() {
  137. if walker(e) {
  138. return
  139. }
  140. }
  141. }
  142. func (n *network) EndpointByName(name string) (Endpoint, error) {
  143. if name == "" {
  144. return nil, ErrInvalidName(name)
  145. }
  146. var e Endpoint
  147. s := func(current Endpoint) bool {
  148. if current.Name() == name {
  149. e = current
  150. return true
  151. }
  152. return false
  153. }
  154. n.WalkEndpoints(s)
  155. if e == nil {
  156. return nil, ErrNoSuchEndpoint(name)
  157. }
  158. return e, nil
  159. }
  160. func (n *network) EndpointByID(id string) (Endpoint, error) {
  161. if id == "" {
  162. return nil, ErrInvalidID(id)
  163. }
  164. n.Lock()
  165. defer n.Unlock()
  166. if e, ok := n.endpoints[types.UUID(id)]; ok {
  167. return e, nil
  168. }
  169. return nil, ErrNoSuchEndpoint(id)
  170. }