drvregistry.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. package drvregistry
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "sync"
  7. "github.com/docker/docker/pkg/plugingetter"
  8. "github.com/docker/libnetwork/driverapi"
  9. "github.com/docker/libnetwork/ipamapi"
  10. "github.com/docker/libnetwork/types"
  11. )
  12. type driverData struct {
  13. driver driverapi.Driver
  14. capability driverapi.Capability
  15. }
  16. type ipamData struct {
  17. driver ipamapi.Ipam
  18. capability *ipamapi.Capability
  19. // default address spaces are provided by ipam driver at registration time
  20. defaultLocalAddressSpace, defaultGlobalAddressSpace string
  21. }
  22. type driverTable map[string]*driverData
  23. type ipamTable map[string]*ipamData
  24. // DrvRegistry holds the registry of all network drivers and IPAM drivers that it knows about.
  25. type DrvRegistry struct {
  26. sync.Mutex
  27. drivers driverTable
  28. ipamDrivers ipamTable
  29. dfn DriverNotifyFunc
  30. ifn IPAMNotifyFunc
  31. pluginGetter plugingetter.PluginGetter
  32. }
  33. // Functors definition
  34. // InitFunc defines the driver initialization function signature.
  35. type InitFunc func(driverapi.DriverCallback, map[string]interface{}) error
  36. // IPAMWalkFunc defines the IPAM driver table walker function signature.
  37. type IPAMWalkFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool
  38. // DriverWalkFunc defines the network driver table walker function signature.
  39. type DriverWalkFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) bool
  40. // IPAMNotifyFunc defines the notify function signature when a new IPAM driver gets registered.
  41. type IPAMNotifyFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) error
  42. // DriverNotifyFunc defines the notify function signature when a new network driver gets registered.
  43. type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error
  44. // New retruns a new driver registry handle.
  45. func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc, pg plugingetter.PluginGetter) (*DrvRegistry, error) {
  46. r := &DrvRegistry{
  47. drivers: make(driverTable),
  48. ipamDrivers: make(ipamTable),
  49. dfn: dfn,
  50. ifn: ifn,
  51. pluginGetter: pg,
  52. }
  53. return r, nil
  54. }
  55. // AddDriver adds a network driver to the registry.
  56. func (r *DrvRegistry) AddDriver(ntype string, fn InitFunc, config map[string]interface{}) error {
  57. return fn(r, config)
  58. }
  59. // WalkIPAMs walks the IPAM drivers registered in the registry and invokes the passed walk function and each one of them.
  60. func (r *DrvRegistry) WalkIPAMs(ifn IPAMWalkFunc) {
  61. type ipamVal struct {
  62. name string
  63. data *ipamData
  64. }
  65. r.Lock()
  66. ivl := make([]ipamVal, 0, len(r.ipamDrivers))
  67. for k, v := range r.ipamDrivers {
  68. ivl = append(ivl, ipamVal{name: k, data: v})
  69. }
  70. r.Unlock()
  71. for _, iv := range ivl {
  72. if ifn(iv.name, iv.data.driver, iv.data.capability) {
  73. break
  74. }
  75. }
  76. }
  77. // WalkDrivers walks the network drivers registered in the registry and invokes the passed walk function and each one of them.
  78. func (r *DrvRegistry) WalkDrivers(dfn DriverWalkFunc) {
  79. type driverVal struct {
  80. name string
  81. data *driverData
  82. }
  83. r.Lock()
  84. dvl := make([]driverVal, 0, len(r.drivers))
  85. for k, v := range r.drivers {
  86. dvl = append(dvl, driverVal{name: k, data: v})
  87. }
  88. r.Unlock()
  89. for _, dv := range dvl {
  90. if dfn(dv.name, dv.data.driver, dv.data.capability) {
  91. break
  92. }
  93. }
  94. }
  95. // Driver returns the actual network driver instance and its capability which registered with the passed name.
  96. func (r *DrvRegistry) Driver(name string) (driverapi.Driver, *driverapi.Capability) {
  97. r.Lock()
  98. defer r.Unlock()
  99. d, ok := r.drivers[name]
  100. if !ok {
  101. return nil, nil
  102. }
  103. return d.driver, &d.capability
  104. }
  105. // IPAM returns the actual IPAM driver instance and its capability which registered with the passed name.
  106. func (r *DrvRegistry) IPAM(name string) (ipamapi.Ipam, *ipamapi.Capability) {
  107. r.Lock()
  108. defer r.Unlock()
  109. i, ok := r.ipamDrivers[name]
  110. if !ok {
  111. return nil, nil
  112. }
  113. return i.driver, i.capability
  114. }
  115. // IPAMDefaultAddressSpaces returns the default address space strings for the passed IPAM driver name.
  116. func (r *DrvRegistry) IPAMDefaultAddressSpaces(name string) (string, string, error) {
  117. r.Lock()
  118. defer r.Unlock()
  119. i, ok := r.ipamDrivers[name]
  120. if !ok {
  121. return "", "", fmt.Errorf("ipam %s not found", name)
  122. }
  123. return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil
  124. }
  125. // GetPluginGetter returns the plugingetter
  126. func (r *DrvRegistry) GetPluginGetter() plugingetter.PluginGetter {
  127. return r.pluginGetter
  128. }
  129. // RegisterDriver registers the network driver when it gets discovered.
  130. func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
  131. if strings.TrimSpace(ntype) == "" {
  132. return errors.New("network type string cannot be empty")
  133. }
  134. r.Lock()
  135. dd, ok := r.drivers[ntype]
  136. r.Unlock()
  137. if ok && dd.driver.IsBuiltIn() {
  138. return driverapi.ErrActiveRegistration(ntype)
  139. }
  140. if r.dfn != nil {
  141. if err := r.dfn(ntype, driver, capability); err != nil {
  142. return err
  143. }
  144. }
  145. dData := &driverData{driver, capability}
  146. r.Lock()
  147. r.drivers[ntype] = dData
  148. r.Unlock()
  149. return nil
  150. }
  151. func (r *DrvRegistry) registerIpamDriver(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error {
  152. if strings.TrimSpace(name) == "" {
  153. return errors.New("ipam driver name string cannot be empty")
  154. }
  155. r.Lock()
  156. dd, ok := r.ipamDrivers[name]
  157. r.Unlock()
  158. if ok && dd.driver.IsBuiltIn() {
  159. return types.ForbiddenErrorf("ipam driver %q already registered", name)
  160. }
  161. locAS, glbAS, err := driver.GetDefaultAddressSpaces()
  162. if err != nil {
  163. return types.InternalErrorf("ipam driver %q failed to return default address spaces: %v", name, err)
  164. }
  165. if r.ifn != nil {
  166. if err := r.ifn(name, driver, caps); err != nil {
  167. return err
  168. }
  169. }
  170. r.Lock()
  171. r.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS, capability: caps}
  172. r.Unlock()
  173. return nil
  174. }
  175. // RegisterIpamDriver registers the IPAM driver discovered with default capabilities.
  176. func (r *DrvRegistry) RegisterIpamDriver(name string, driver ipamapi.Ipam) error {
  177. return r.registerIpamDriver(name, driver, &ipamapi.Capability{})
  178. }
  179. // RegisterIpamDriverWithCapabilities registers the IPAM driver discovered with specified capabilities.
  180. func (r *DrvRegistry) RegisterIpamDriverWithCapabilities(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error {
  181. return r.registerIpamDriver(name, driver, caps)
  182. }