controller.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. Package libnetwork provides the basic functionality and extension points to
  3. create network namespaces and allocate interfaces for containers to use.
  4. // Create a new controller instance
  5. controller, _err := libnetwork.New()
  6. // Select and configure the network driver
  7. networkType := "bridge"
  8. driverOptions := options.Generic{}
  9. genericOption := make(map[string]interface{})
  10. genericOption[netlabel.GenericData] = driverOptions
  11. err := controller.ConfigureNetworkDriver(networkType, genericOption)
  12. if err != nil {
  13. return
  14. }
  15. // Create a network for containers to join.
  16. // NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make of
  17. network, err := controller.NewNetwork(networkType, "network1")
  18. if err != nil {
  19. return
  20. }
  21. // For each new container: allocate IP and interfaces. The returned network
  22. // settings will be used for container infos (inspect and such), as well as
  23. // iptables rules for port publishing. This info is contained or accessible
  24. // from the returned endpoint.
  25. ep, err := network.CreateEndpoint("Endpoint1")
  26. if err != nil {
  27. return
  28. }
  29. // A container can join the endpoint by providing the container ID to the join
  30. // api which returns the sandbox key which can be used to access the sandbox
  31. // created for the container during join.
  32. // Join acceps Variadic arguments which will be made use of by libnetwork and Drivers
  33. _, err = ep.Join("container1",
  34. libnetwork.JoinOptionHostname("test"),
  35. libnetwork.JoinOptionDomainname("docker.io"))
  36. if err != nil {
  37. return
  38. }
  39. */
  40. package libnetwork
  41. import (
  42. "encoding/json"
  43. "errors"
  44. "fmt"
  45. "sync"
  46. log "github.com/Sirupsen/logrus"
  47. "github.com/docker/docker/pkg/plugins"
  48. "github.com/docker/docker/pkg/stringid"
  49. "github.com/docker/libnetwork/datastore"
  50. "github.com/docker/libnetwork/driverapi"
  51. "github.com/docker/libnetwork/sandbox"
  52. "github.com/docker/libnetwork/types"
  53. "github.com/docker/swarm/pkg/store"
  54. )
  55. // TODO: Move it to error.go once the error refactoring is done
  56. var ErrInvalidDatastore = errors.New("Datastore is not initialized")
  57. // NetworkController provides the interface for controller instance which manages
  58. // networks.
  59. type NetworkController interface {
  60. // ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
  61. ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
  62. // Create a new network. The options parameter carries network specific options.
  63. // Labels support will be added in the near future.
  64. NewNetwork(networkType, name string, options ...NetworkOption) (Network, error)
  65. // Networks returns the list of Network(s) managed by this controller.
  66. Networks() []Network
  67. // WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
  68. WalkNetworks(walker NetworkWalker)
  69. // NetworkByName returns the Network which has the passed name. If not found, the error ErrNoSuchNetwork is returned.
  70. NetworkByName(name string) (Network, error)
  71. // NetworkByID returns the Network which has the passed id. If not found, the error ErrNoSuchNetwork is returned.
  72. NetworkByID(id string) (Network, error)
  73. }
  74. // NetworkWalker is a client provided function which will be used to walk the Networks.
  75. // When the function returns true, the walk will stop.
  76. type NetworkWalker func(nw Network) bool
  77. type sandboxData struct {
  78. sandbox sandbox.Sandbox
  79. refCnt int
  80. }
  81. type networkTable map[types.UUID]*network
  82. type endpointTable map[types.UUID]*endpoint
  83. type sandboxTable map[string]*sandboxData
  84. type controller struct {
  85. networks networkTable
  86. drivers driverTable
  87. sandboxes sandboxTable
  88. store datastore.DataStore
  89. sync.Mutex
  90. }
  91. // New creates a new instance of network controller.
  92. func New() (NetworkController, error) {
  93. c := &controller{
  94. networks: networkTable{},
  95. sandboxes: sandboxTable{},
  96. drivers: driverTable{}}
  97. if err := initDrivers(c); err != nil {
  98. return nil, err
  99. }
  100. if err := c.initDataStore(); err != nil {
  101. log.Errorf("Failed to Initialize Datastore : %v", err)
  102. // TODO : Should we fail if the initDataStore fail here ?
  103. }
  104. go c.watchNewNetworks()
  105. return c, nil
  106. }
  107. func (c *controller) initDataStore() error {
  108. /* TODO : Duh ! make this configurable */
  109. config := &datastore.StoreConfiguration{}
  110. config.Provider = "consul"
  111. config.Addrs = []string{"localhost:8500"}
  112. store, err := datastore.NewDataStore(config)
  113. if err != nil {
  114. return err
  115. }
  116. c.Lock()
  117. c.store = store
  118. c.Unlock()
  119. return nil
  120. }
  121. func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {
  122. c.Lock()
  123. d, ok := c.drivers[networkType]
  124. c.Unlock()
  125. if !ok {
  126. return NetworkTypeError(networkType)
  127. }
  128. return d.Config(options)
  129. }
  130. func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver) error {
  131. c.Lock()
  132. defer c.Unlock()
  133. if _, ok := c.drivers[networkType]; ok {
  134. return driverapi.ErrActiveRegistration(networkType)
  135. }
  136. c.drivers[networkType] = driver
  137. return nil
  138. }
  139. // NewNetwork creates a new network of the specified network type. The options
  140. // are network specific and modeled in a generic way.
  141. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) {
  142. if name == "" {
  143. return nil, ErrInvalidName(name)
  144. }
  145. // Check if a driver for the specified network type is available
  146. c.Lock()
  147. d, ok := c.drivers[networkType]
  148. c.Unlock()
  149. if !ok {
  150. var err error
  151. d, err = c.loadDriver(networkType)
  152. if err != nil {
  153. return nil, err
  154. }
  155. }
  156. // Check if a network already exists with the specified network name
  157. c.Lock()
  158. for _, n := range c.networks {
  159. if n.name == name {
  160. c.Unlock()
  161. return nil, NetworkNameError(name)
  162. }
  163. }
  164. c.Unlock()
  165. // Construct the network object
  166. network := &network{
  167. name: name,
  168. id: types.UUID(stringid.GenerateRandomID()),
  169. ctrlr: c,
  170. driver: d,
  171. endpoints: endpointTable{},
  172. }
  173. network.processOptions(options...)
  174. if err := c.addNetworkToStore(network); err != nil {
  175. return nil, err
  176. }
  177. // Create the network
  178. if err := d.CreateNetwork(network.id, network.generic); err != nil {
  179. return nil, err
  180. }
  181. // Store the network handler in controller
  182. c.Lock()
  183. c.networks[network.id] = network
  184. c.Unlock()
  185. return network, nil
  186. }
  187. func (c *controller) newNetworkFromStore(n *network) {
  188. c.Lock()
  189. defer c.Unlock()
  190. if _, ok := c.drivers[n.networkType]; !ok {
  191. log.Warnf("Network driver unavailable for type=%s. ignoring network updates for %s", n.Type(), n.Name())
  192. return
  193. }
  194. n.ctrlr = c
  195. n.driver = c.drivers[n.networkType]
  196. c.networks[n.id] = n
  197. // TODO : Populate n.endpoints back from endpoint dbstore
  198. }
  199. func (c *controller) addNetworkToStore(n *network) error {
  200. if IsReservedNetwork(n.Name()) {
  201. return nil
  202. }
  203. if c.store == nil {
  204. return ErrInvalidDatastore
  205. }
  206. return c.store.PutObjectAtomic(n)
  207. }
  208. func (c *controller) watchNewNetworks() {
  209. c.Lock()
  210. store = c.store
  211. c.Unlock()
  212. store.KVStore().WatchRange(datastore.Key("network"), "", 0, func(kvi []store.KVEntry) {
  213. for _, kve := range kvi {
  214. var n network
  215. err := json.Unmarshal(kve.Value(), &n)
  216. if err != nil {
  217. log.Error(err)
  218. continue
  219. }
  220. n.dbIndex = kve.LastIndex()
  221. c.Lock()
  222. existing, ok := c.networks[n.id]
  223. c.Unlock()
  224. if ok && existing.dbIndex == n.dbIndex {
  225. // Skip any watch notification for a network that has not changed
  226. continue
  227. }
  228. fmt.Printf("WATCHED : %v = %v\n", kve.Key(), n)
  229. c.newNetworkFromStore(&n)
  230. }
  231. })
  232. }
  233. func (c *controller) Networks() []Network {
  234. c.Lock()
  235. defer c.Unlock()
  236. list := make([]Network, 0, len(c.networks))
  237. for _, n := range c.networks {
  238. list = append(list, n)
  239. }
  240. return list
  241. }
  242. func (c *controller) WalkNetworks(walker NetworkWalker) {
  243. for _, n := range c.Networks() {
  244. if walker(n) {
  245. return
  246. }
  247. }
  248. }
  249. func (c *controller) NetworkByName(name string) (Network, error) {
  250. if name == "" {
  251. return nil, ErrInvalidName(name)
  252. }
  253. var n Network
  254. s := func(current Network) bool {
  255. if current.Name() == name {
  256. n = current
  257. return true
  258. }
  259. return false
  260. }
  261. c.WalkNetworks(s)
  262. if n == nil {
  263. return nil, ErrNoSuchNetwork(name)
  264. }
  265. return n, nil
  266. }
  267. func (c *controller) NetworkByID(id string) (Network, error) {
  268. if id == "" {
  269. return nil, ErrInvalidID(id)
  270. }
  271. c.Lock()
  272. defer c.Unlock()
  273. if n, ok := c.networks[types.UUID(id)]; ok {
  274. return n, nil
  275. }
  276. return nil, ErrNoSuchNetwork(id)
  277. }
  278. func (c *controller) sandboxAdd(key string, create bool) (sandbox.Sandbox, error) {
  279. c.Lock()
  280. defer c.Unlock()
  281. sData, ok := c.sandboxes[key]
  282. if !ok {
  283. sb, err := sandbox.NewSandbox(key, create)
  284. if err != nil {
  285. return nil, err
  286. }
  287. sData = &sandboxData{sandbox: sb, refCnt: 1}
  288. c.sandboxes[key] = sData
  289. return sData.sandbox, nil
  290. }
  291. sData.refCnt++
  292. return sData.sandbox, nil
  293. }
  294. func (c *controller) sandboxRm(key string) {
  295. c.Lock()
  296. defer c.Unlock()
  297. sData := c.sandboxes[key]
  298. sData.refCnt--
  299. if sData.refCnt == 0 {
  300. sData.sandbox.Destroy()
  301. delete(c.sandboxes, key)
  302. }
  303. }
  304. func (c *controller) sandboxGet(key string) sandbox.Sandbox {
  305. c.Lock()
  306. defer c.Unlock()
  307. sData, ok := c.sandboxes[key]
  308. if !ok {
  309. return nil
  310. }
  311. return sData.sandbox
  312. }
  313. func (c *controller) loadDriver(networkType string) (driverapi.Driver, error) {
  314. // Plugins pkg performs lazy loading of plugins that acts as remote drivers.
  315. // As per the design, this Get call will result in remote driver discovery if there is a corresponding plugin available.
  316. _, err := plugins.Get(networkType, driverapi.NetworkPluginEndpointType)
  317. if err != nil {
  318. if err == plugins.ErrNotFound {
  319. return nil, types.NotFoundErrorf(err.Error())
  320. }
  321. return nil, err
  322. }
  323. c.Lock()
  324. defer c.Unlock()
  325. d, ok := c.drivers[networkType]
  326. if !ok {
  327. return nil, ErrInvalidNetworkDriver(networkType)
  328. }
  329. return d, nil
  330. }