networks.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package drvregistry
  2. import (
  3. "errors"
  4. "strings"
  5. "sync"
  6. "github.com/docker/docker/libnetwork/driverapi"
  7. )
  8. // DriverWalkFunc defines the network driver table walker function signature.
  9. type DriverWalkFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) bool
  10. // DriverNotifyFunc defines the notify function signature when a new network driver gets registered.
  11. type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error
  12. type driverData struct {
  13. driver driverapi.Driver
  14. capability driverapi.Capability
  15. }
  16. // Networks is a registry of network drivers. The zero value is an empty network
  17. // driver registry, ready to use.
  18. type Networks struct {
  19. // Notify is called whenever a network driver is registered.
  20. Notify DriverNotifyFunc
  21. mu sync.Mutex
  22. drivers map[string]driverData
  23. }
  24. var _ driverapi.Registerer = (*Networks)(nil)
  25. // WalkDrivers walks the network drivers registered in the registry and invokes the passed walk function and each one of them.
  26. func (nr *Networks) WalkDrivers(dfn DriverWalkFunc) {
  27. type driverVal struct {
  28. name string
  29. data driverData
  30. }
  31. nr.mu.Lock()
  32. dvl := make([]driverVal, 0, len(nr.drivers))
  33. for k, v := range nr.drivers {
  34. dvl = append(dvl, driverVal{name: k, data: v})
  35. }
  36. nr.mu.Unlock()
  37. for _, dv := range dvl {
  38. if dfn(dv.name, dv.data.driver, dv.data.capability) {
  39. break
  40. }
  41. }
  42. }
  43. // Driver returns the network driver instance registered under name, and its capability.
  44. func (nr *Networks) Driver(name string) (driverapi.Driver, driverapi.Capability) {
  45. nr.mu.Lock()
  46. defer nr.mu.Unlock()
  47. d := nr.drivers[name]
  48. return d.driver, d.capability
  49. }
  50. // RegisterDriver registers the network driver with nr.
  51. func (nr *Networks) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error {
  52. if strings.TrimSpace(ntype) == "" {
  53. return errors.New("network type string cannot be empty")
  54. }
  55. nr.mu.Lock()
  56. dd, ok := nr.drivers[ntype]
  57. nr.mu.Unlock()
  58. if ok && dd.driver.IsBuiltIn() {
  59. return driverapi.ErrActiveRegistration(ntype)
  60. }
  61. if nr.Notify != nil {
  62. if err := nr.Notify(ntype, driver, capability); err != nil {
  63. return err
  64. }
  65. }
  66. nr.mu.Lock()
  67. defer nr.mu.Unlock()
  68. if nr.drivers == nil {
  69. nr.drivers = make(map[string]driverData)
  70. }
  71. nr.drivers[ntype] = driverData{driver: driver, capability: capability}
  72. return nil
  73. }