| package drvregistry |
| |
| import ( |
| "errors" |
| "strings" |
| "sync" |
| |
| "github.com/docker/docker/libnetwork/driverapi" |
| ) |
| |
| // DriverWalkFunc defines the network driver table walker function signature. |
| type DriverWalkFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) bool |
| |
| type driverData struct { |
| driver driverapi.Driver |
| capability driverapi.Capability |
| } |
| |
| // Networks is a registry of network drivers. The zero value is an empty network |
| // driver registry, ready to use. |
| type Networks struct { |
| // Notify is called whenever a network driver is registered. |
| Notify driverapi.Registerer |
| |
| mu sync.Mutex |
| drivers map[string]driverData |
| } |
| |
| var _ driverapi.Registerer = (*Networks)(nil) |
| |
| // WalkDrivers walks the network drivers registered in the registry and invokes the passed walk function and each one of them. |
| func (nr *Networks) WalkDrivers(dfn DriverWalkFunc) { |
| type driverVal struct { |
| name string |
| data driverData |
| } |
| |
| nr.mu.Lock() |
| dvl := make([]driverVal, 0, len(nr.drivers)) |
| for k, v := range nr.drivers { |
| dvl = append(dvl, driverVal{name: k, data: v}) |
| } |
| nr.mu.Unlock() |
| |
| for _, dv := range dvl { |
| if dfn(dv.name, dv.data.driver, dv.data.capability) { |
| break |
| } |
| } |
| } |
| |
| // Driver returns the network driver instance registered under name, and its capability. |
| func (nr *Networks) Driver(name string) (driverapi.Driver, driverapi.Capability) { |
| nr.mu.Lock() |
| defer nr.mu.Unlock() |
| |
| d := nr.drivers[name] |
| return d.driver, d.capability |
| } |
| |
| // RegisterDriver registers the network driver with nr. |
| func (nr *Networks) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error { |
| if strings.TrimSpace(ntype) == "" { |
| return errors.New("network type string cannot be empty") |
| } |
| |
| nr.mu.Lock() |
| dd, ok := nr.drivers[ntype] |
| nr.mu.Unlock() |
| |
| if ok && dd.driver.IsBuiltIn() { |
| return driverapi.ErrActiveRegistration(ntype) |
| } |
| |
| if nr.Notify != nil { |
| if err := nr.Notify.RegisterDriver(ntype, driver, capability); err != nil { |
| return err |
| } |
| } |
| |
| nr.mu.Lock() |
| defer nr.mu.Unlock() |
| |
| if nr.drivers == nil { |
| nr.drivers = make(map[string]driverData) |
| } |
| nr.drivers[ntype] = driverData{driver: driver, capability: capability} |
| |
| return nil |
| } |