moby/libnetwork/drvregistry/networks.go
Cory Snider a0a8d9d057 libnetwork: notify another driver registerer
There is no meaningful distinction between driverapi.Registerer and
drvregistry.DriverNotifyFunc. They are both used to register a network
driver with an interested party. They have the same function signature.
The only difference is that the latter could be satisfied by an
anonymous closure. However, in practice the only implementation of
drvregistry.DriverNotifyFunc is the
(*libnetwork.Controller).RegisterDriver method. This same method also
makes the libnetwork.Controller type satisfy the Registerer interface,
therefore the DriverNotifyFunc type is redundant. Change
drvregistry.Networks to notify a Registerer and drop the
DriverNotifyFunc type.

Signed-off-by: Cory Snider <csnider@mirantis.com>
2023-08-29 10:32:18 -04:00

90 lines
2.2 KiB
Go

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
}