networks.go 2.2 KB

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