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  }