| 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 | |
| } |