github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drvregistry/drvregistry.go (about) 1 package drvregistry 2 3 import ( 4 "fmt" 5 "strings" 6 "sync" 7 8 "github.com/docker/docker/pkg/plugingetter" 9 "github.com/docker/libnetwork/driverapi" 10 "github.com/docker/libnetwork/ipamapi" 11 "github.com/docker/libnetwork/types" 12 ) 13 14 type driverData struct { 15 driver driverapi.Driver 16 capability driverapi.Capability 17 } 18 19 type ipamData struct { 20 driver ipamapi.Ipam 21 capability *ipamapi.Capability 22 // default address spaces are provided by ipam driver at registration time 23 defaultLocalAddressSpace, defaultGlobalAddressSpace string 24 } 25 26 type driverTable map[string]*driverData 27 type ipamTable map[string]*ipamData 28 29 // DrvRegistry holds the registry of all network drivers and IPAM drivers that it knows about. 30 type DrvRegistry struct { 31 sync.Mutex 32 drivers driverTable 33 ipamDrivers ipamTable 34 dfn DriverNotifyFunc 35 ifn IPAMNotifyFunc 36 pluginGetter plugingetter.PluginGetter 37 } 38 39 // Functors definition 40 41 // InitFunc defines the driver initialization function signature. 42 type InitFunc func(driverapi.DriverCallback, map[string]interface{}) error 43 44 // IPAMWalkFunc defines the IPAM driver table walker function signature. 45 type IPAMWalkFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) bool 46 47 // DriverWalkFunc defines the network driver table walker function signature. 48 type DriverWalkFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) bool 49 50 // IPAMNotifyFunc defines the notify function signature when a new IPAM driver gets registered. 51 type IPAMNotifyFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capability) error 52 53 // DriverNotifyFunc defines the notify function signature when a new network driver gets registered. 54 type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error 55 56 // New retruns a new driver registry handle. 57 func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc, pg plugingetter.PluginGetter) (*DrvRegistry, error) { 58 r := &DrvRegistry{ 59 drivers: make(driverTable), 60 ipamDrivers: make(ipamTable), 61 dfn: dfn, 62 ifn: ifn, 63 pluginGetter: pg, 64 } 65 66 return r, nil 67 } 68 69 // AddDriver adds a network driver to the registry. 70 func (r *DrvRegistry) AddDriver(ntype string, fn InitFunc, config map[string]interface{}) error { 71 return fn(r, config) 72 } 73 74 // WalkIPAMs walks the IPAM drivers registered in the registry and invokes the passed walk function and each one of them. 75 func (r *DrvRegistry) WalkIPAMs(ifn IPAMWalkFunc) { 76 type ipamVal struct { 77 name string 78 data *ipamData 79 } 80 81 r.Lock() 82 ivl := make([]ipamVal, 0, len(r.ipamDrivers)) 83 for k, v := range r.ipamDrivers { 84 ivl = append(ivl, ipamVal{name: k, data: v}) 85 } 86 r.Unlock() 87 88 for _, iv := range ivl { 89 if ifn(iv.name, iv.data.driver, iv.data.capability) { 90 break 91 } 92 } 93 } 94 95 // WalkDrivers walks the network drivers registered in the registry and invokes the passed walk function and each one of them. 96 func (r *DrvRegistry) WalkDrivers(dfn DriverWalkFunc) { 97 type driverVal struct { 98 name string 99 data *driverData 100 } 101 102 r.Lock() 103 dvl := make([]driverVal, 0, len(r.drivers)) 104 for k, v := range r.drivers { 105 dvl = append(dvl, driverVal{name: k, data: v}) 106 } 107 r.Unlock() 108 109 for _, dv := range dvl { 110 if dfn(dv.name, dv.data.driver, dv.data.capability) { 111 break 112 } 113 } 114 } 115 116 // Driver returns the actual network driver instance and its capability which registered with the passed name. 117 func (r *DrvRegistry) Driver(name string) (driverapi.Driver, *driverapi.Capability) { 118 r.Lock() 119 defer r.Unlock() 120 121 d, ok := r.drivers[name] 122 if !ok { 123 return nil, nil 124 } 125 126 return d.driver, &d.capability 127 } 128 129 // IPAM returns the actual IPAM driver instance and its capability which registered with the passed name. 130 func (r *DrvRegistry) IPAM(name string) (ipamapi.Ipam, *ipamapi.Capability) { 131 r.Lock() 132 defer r.Unlock() 133 134 i, ok := r.ipamDrivers[name] 135 if !ok { 136 return nil, nil 137 } 138 139 return i.driver, i.capability 140 } 141 142 // IPAMDefaultAddressSpaces returns the default address space strings for the passed IPAM driver name. 143 func (r *DrvRegistry) IPAMDefaultAddressSpaces(name string) (string, string, error) { 144 r.Lock() 145 defer r.Unlock() 146 147 i, ok := r.ipamDrivers[name] 148 if !ok { 149 return "", "", fmt.Errorf("ipam %s not found", name) 150 } 151 152 return i.defaultLocalAddressSpace, i.defaultGlobalAddressSpace, nil 153 } 154 155 // GetPluginGetter returns the plugingetter 156 func (r *DrvRegistry) GetPluginGetter() plugingetter.PluginGetter { 157 return r.pluginGetter 158 } 159 160 // RegisterDriver registers the network driver when it gets discovered. 161 func (r *DrvRegistry) RegisterDriver(ntype string, driver driverapi.Driver, capability driverapi.Capability) error { 162 if strings.TrimSpace(ntype) == "" { 163 return fmt.Errorf("network type string cannot be empty") 164 } 165 166 r.Lock() 167 _, ok := r.drivers[ntype] 168 r.Unlock() 169 170 if ok { 171 return driverapi.ErrActiveRegistration(ntype) 172 } 173 174 if r.dfn != nil { 175 if err := r.dfn(ntype, driver, capability); err != nil { 176 return err 177 } 178 } 179 180 dData := &driverData{driver, capability} 181 182 r.Lock() 183 r.drivers[ntype] = dData 184 r.Unlock() 185 186 return nil 187 } 188 189 func (r *DrvRegistry) registerIpamDriver(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error { 190 if strings.TrimSpace(name) == "" { 191 return fmt.Errorf("ipam driver name string cannot be empty") 192 } 193 194 r.Lock() 195 _, ok := r.ipamDrivers[name] 196 r.Unlock() 197 if ok { 198 return types.ForbiddenErrorf("ipam driver %q already registered", name) 199 } 200 201 locAS, glbAS, err := driver.GetDefaultAddressSpaces() 202 if err != nil { 203 return types.InternalErrorf("ipam driver %q failed to return default address spaces: %v", name, err) 204 } 205 206 if r.ifn != nil { 207 if err := r.ifn(name, driver, caps); err != nil { 208 return err 209 } 210 } 211 212 r.Lock() 213 r.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS, capability: caps} 214 r.Unlock() 215 216 return nil 217 } 218 219 // RegisterIpamDriver registers the IPAM driver discovered with default capabilities. 220 func (r *DrvRegistry) RegisterIpamDriver(name string, driver ipamapi.Ipam) error { 221 return r.registerIpamDriver(name, driver, &ipamapi.Capability{}) 222 } 223 224 // RegisterIpamDriverWithCapabilities registers the IPAM driver discovered with specified capabilities. 225 func (r *DrvRegistry) RegisterIpamDriverWithCapabilities(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error { 226 return r.registerIpamDriver(name, driver, caps) 227 }