drvregistry.go 6.3 KB

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