// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Construct the network object network := &network{ name: name, networkType: networkType, ipamType: ipamapi.DefaultIPAM, id: stringid.GenerateRandomID(), ctrlr: c, persist: true, drvOnce: &sync.Once{}, } network.processOptions(options...) // Make sure we have a driver available for this network type // before we allocate anything. if _, err := network.driver(); err != nil { return nil, err } cnfs, err := network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { for _, cn := range cnfs { cn() } } }() // addNetwork can be called for local scope network lazily when // an endpoint is created after a restart and the network was // created in previous life. Make sure you wrap around the driver // notification of network creation in once call so that the driver // invoked only once in case both the network and endpoint creation // happens in the same lifetime. network.drvOnce.Do(func() { err = c.addNetwork(network) }) if err != nil { return nil, err } if err = c.updateToStore(network); err != nil { log.Warnf("couldnt create network %s: %v", network.name, err) if e := network.Delete(); e != nil { log.Warnf("couldnt cleanup network %s on network create failure (%v): %v", network.name, err, e) } return nil, err } return network, nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Check if a network already exists with the specified network name c.Lock() for _, n := range c.networks { if n.name == name { c.Unlock() return nil, NetworkNameError(name) } } c.Unlock() // Construct the network object network := &network{ name: name, networkType: networkType, ipamType: ipamapi.DefaultIPAM, id: stringid.GenerateRandomID(), ctrlr: c, endpoints: endpointTable{}, persist: true, } network.processOptions(options...) if _, err := c.loadNetworkDriver(network); err != nil { return nil, err } cnfs, err := network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { for _, cn := range cnfs { cn() } } }() if err = c.addNetwork(network); err != nil { return nil, err } if err = c.updateToStore(network); err != nil { log.Warnf("couldnt create network %s: %v", network.name, err) if e := network.Delete(); e != nil { log.Warnf("couldnt cleanup network %s on network create failure (%v): %v", network.name, err, e) } return nil, err } return network, nil }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if _, err = n.EndpointByName(name); err == nil { return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name) } ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} ep.id = stringid.GenerateRandomID() ep.network = n ep.processOptions(options...) if err = ep.assignAddress(); err != nil { return nil, err } defer func() { if err != nil { ep.releaseAddress() } }() ctrlr := n.getController() n.IncEndpointCnt() if err = ctrlr.updateToStore(n); err != nil { return nil, err } defer func() { if err != nil { n.DecEndpointCnt() if err = ctrlr.updateToStore(n); err != nil { log.Warnf("endpoint count cleanup failed when updating network for %s : %v", name, err) } } }() if err = n.addEndpoint(ep); err != nil { return nil, err } defer func() { if err != nil { if e := ep.Delete(); ep != nil { log.Warnf("cleaning up endpoint failed %s : %v", name, e) } } }() if !ep.isLocalScoped() { if err = ctrlr.updateToStore(ep); err != nil { return nil, err } } return ep, nil }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if _, err = n.EndpointByName(name); err == nil { return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name) } ep := &endpoint{name: name, iFaces: []*endpointInterface{}, generic: make(map[string]interface{})} ep.id = types.UUID(stringid.GenerateRandomID()) ep.network = n ep.processOptions(options...) n.Lock() ctrlr := n.ctrlr n.Unlock() n.IncEndpointCnt() if err = ctrlr.updateNetworkToStore(n); err != nil { return nil, err } defer func() { if err != nil { n.DecEndpointCnt() if err = ctrlr.updateNetworkToStore(n); err != nil { log.Warnf("endpoint count cleanup failed when updating network for %s : %v", name, err) } } }() if err = n.addEndpoint(ep); err != nil { return nil, err } defer func() { if err != nil { if e := ep.Delete(); ep != nil { log.Warnf("cleaning up endpoint failed %s : %v", name, e) } } }() if err = ctrlr.updateEndpointToStore(ep); err != nil { return nil, err } return ep, nil }
func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error { if !config.IsValidName(networkType) { return ErrInvalidName(networkType) } c.Lock() if _, ok := c.drivers[networkType]; ok { c.Unlock() return driverapi.ErrActiveRegistration(networkType) } c.drivers[networkType] = &driverData{driver, capability} c.Unlock() return nil }
func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error { c.Lock() if !config.IsValidName(networkType) { c.Unlock() return ErrInvalidName(networkType) } if _, ok := c.drivers[networkType]; ok { c.Unlock() return driverapi.ErrActiveRegistration(networkType) } c.drivers[networkType] = &driverData{driver, capability} if c.cfg == nil { c.Unlock() return nil } opt := make(map[string]interface{}) for _, label := range c.cfg.Daemon.Labels { if strings.HasPrefix(label, netlabel.DriverPrefix+"."+networkType) { opt[netlabel.Key(label)] = netlabel.Value(label) } } if capability.DataScope == datastore.GlobalScope && c.validateGlobalStoreConfig() { opt[netlabel.KVProvider] = c.cfg.GlobalStore.Client.Provider opt[netlabel.KVProviderURL] = c.cfg.GlobalStore.Client.Address } if capability.DataScope == datastore.LocalScope { localStoreConfig := c.getLocalStoreConfig(c.cfg) opt[netlabel.KVProvider] = localStoreConfig.Client.Provider opt[netlabel.KVProviderURL] = localStoreConfig.Client.Address opt[netlabel.KVProviderConfig] = localStoreConfig.Client.Config } c.Unlock() if len(opt) != 0 { if err := driver.Config(opt); err != nil { return err } } return nil }
func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver, capability driverapi.Capability) error { if !config.IsValidName(networkType) { return ErrInvalidName(networkType) } c.Lock() if _, ok := c.drivers[networkType]; ok { c.Unlock() return driverapi.ErrActiveRegistration(networkType) } dData := &driverData{driver, capability} c.drivers[networkType] = dData hd := c.discovery c.Unlock() if hd != nil { c.pushNodeDiscovery(dData, hd.Fetch(), true) } return nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Check if a network already exists with the specified network name c.Lock() for _, n := range c.networks { if n.name == name { c.Unlock() return n, nil // return nil, NetworkNameError(name) } } c.Unlock() // Construct the network object network := &network{ name: name, networkType: networkType, id: stringid.GenerateRandomID(), ctrlr: c, endpoints: endpointTable{}, } network.processOptions(options...) if err := c.addNetwork(network); err != nil { return nil, err } if err := c.updateNetworkToStore(network); err != nil { log.Warnf("couldnt create network %s: %v", network.name, err) if e := network.Delete(); e != nil { log.Warnf("couldnt cleanup network %s: %v", network.name, err) } return nil, err } return network, nil }
func (c *controller) RegisterIpamDriver(name string, driver ipamapi.Ipam) error { if !config.IsValidName(name) { return ErrInvalidName(name) } c.Lock() _, ok := c.ipamDrivers[name] c.Unlock() if ok { return driverapi.ErrActiveRegistration(name) } locAS, glbAS, err := driver.GetDefaultAddressSpaces() if err != nil { return fmt.Errorf("ipam driver %s failed to return default address spaces: %v", name, err) } c.Lock() c.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS} c.Unlock() log.Debugf("Registering ipam provider: %s", name) return nil }
func (c *controller) registerIpamDriver(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error { if !config.IsValidName(name) { return ErrInvalidName(name) } c.Lock() _, ok := c.ipamDrivers[name] c.Unlock() if ok { return types.ForbiddenErrorf("ipam driver %q already registered", name) } locAS, glbAS, err := driver.GetDefaultAddressSpaces() if err != nil { return types.InternalErrorf("ipam driver %q failed to return default address spaces: %v", name, err) } c.Lock() c.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS, capability: caps} c.Unlock() log.Debugf("Registering ipam driver: %q", name) return nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if id == "" { id = stringid.GenerateRandomID() } // Construct the network object network := &network{ name: name, networkType: networkType, generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)}, ipamType: ipamapi.DefaultIPAM, id: id, ctrlr: c, persist: true, drvOnce: &sync.Once{}, } network.processOptions(options...) _, cap, err := network.resolveDriver(networkType, true) if err != nil { return nil, err } if cap.DataScope == datastore.GlobalScope && !c.isDistributedControl() && !network.dynamic { if c.isManager() { // For non-distributed controlled environment, globalscoped non-dynamic networks are redirected to Manager return nil, ManagerRedirectError(name) } return nil, types.ForbiddenErrorf("Cannot create a multi-host network from a worker node. Please create the network from a manager node.") } // Make sure we have a driver available for this network type // before we allocate anything. if _, err := network.driver(true); err != nil { return nil, err } err = network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { network.ipamRelease() } }() err = c.addNetwork(network) if err != nil { return nil, err } defer func() { if err != nil { if e := network.deleteNetwork(); e != nil { log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) } } }() // First store the endpoint count, then the network. To avoid to // end up with a datastore containing a network and not an epCnt, // in case of an ungraceful shutdown during this function call. epCnt := &endpointCnt{n: network} if err = c.updateToStore(epCnt); err != nil { return nil, err } defer func() { if err != nil { if e := c.deleteFromStore(epCnt); e != nil { log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e) } } }() network.epCnt = epCnt if err = c.updateToStore(network); err != nil { return nil, err } joinCluster(network) return network, nil }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if _, err = n.EndpointByName(name); err == nil { return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name) } ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} ep.id = stringid.GenerateRandomID() // Initialize ep.network with a possibly stale copy of n. We need this to get network from // store. But once we get it from store we will have the most uptodate copy possibly. ep.network = n ep.locator = n.getController().clusterHostID() ep.network, err = ep.getNetworkFromStore() if err != nil { return nil, fmt.Errorf("failed to get network during CreateEndpoint: %v", err) } n = ep.network ep.processOptions(options...) for _, llIPNet := range ep.Iface().LinkLocalAddresses() { if !llIPNet.IP.IsLinkLocalUnicast() { return nil, types.BadRequestErrorf("invalid link local IP address: %v", llIPNet.IP) } } if opt, ok := ep.generic[netlabel.MacAddress]; ok { if mac, ok := opt.(net.HardwareAddr); ok { ep.iface.mac = mac } } ipam, cap, err := n.getController().getIPAMDriver(n.ipamType) if err != nil { return nil, err } if cap.RequiresMACAddress { if ep.iface.mac == nil { ep.iface.mac = netutils.GenerateRandomMAC() } if ep.ipamOptions == nil { ep.ipamOptions = make(map[string]string) } ep.ipamOptions[netlabel.MacAddress] = ep.iface.mac.String() } if err = ep.assignAddress(ipam, true, n.enableIPv6 && !n.postIPv6); err != nil { return nil, err } defer func() { if err != nil { ep.releaseAddress() } }() if err = n.addEndpoint(ep); err != nil { return nil, err } defer func() { if err != nil { if e := ep.deleteEndpoint(false); e != nil { log.Warnf("cleaning up endpoint failed %s : %v", name, e) } } }() if err = ep.assignAddress(ipam, false, n.enableIPv6 && n.postIPv6); err != nil { return nil, err } if err = n.getController().updateToStore(ep); err != nil { return nil, err } defer func() { if err != nil { if e := n.getController().deleteFromStore(ep); e != nil { log.Warnf("error rolling back endpoint %s from store: %v", name, e) } } }() // Watch for service records n.getController().watchSvcRecord(ep) defer func() { if err != nil { n.getController().unWatchSvcRecord(ep) } }() // Increment endpoint count to indicate completion of endpoint addition if err = n.getEpCnt().IncEndpointCnt(); err != nil { return nil, err } return ep, nil }
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) { var err error if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if _, err = n.EndpointByName(name); err == nil { return nil, types.ForbiddenErrorf("service endpoint with name %s already exists", name) } ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} ep.id = stringid.GenerateRandomID() // Initialize ep.network with a possibly stale copy of n. We need this to get network from // store. But once we get it from store we will have the most uptodate copy possible. ep.network = n ep.network, err = ep.getNetworkFromStore() if err != nil { return nil, fmt.Errorf("failed to get network during CreateEndpoint: %v", err) } n = ep.network ep.processOptions(options...) if opt, ok := ep.generic[netlabel.MacAddress]; ok { if mac, ok := opt.(net.HardwareAddr); ok { ep.iface.mac = mac } } if err = ep.assignAddress(true, !n.postIPv6); err != nil { return nil, err } defer func() { if err != nil { ep.releaseAddress() } }() if err = n.addEndpoint(ep); err != nil { return nil, err } defer func() { if err != nil { if e := ep.deleteEndpoint(); e != nil { log.Warnf("cleaning up endpoint failed %s : %v", name, e) } } }() if err = ep.assignAddress(false, n.postIPv6); err != nil { return nil, err } if err = n.getController().updateToStore(ep); err != nil { return nil, err } defer func() { if err != nil { if e := n.getController().deleteFromStore(ep); e != nil { log.Warnf("error rolling back endpoint %s from store: %v", name, e) } } }() // Watch for service records n.getController().watchSvcRecord(ep) defer func() { if err != nil { n.getController().unWatchSvcRecord(ep) } }() // Increment endpoint count to indicate completion of endpoint addition if err = n.getEpCnt().IncEndpointCnt(); err != nil { return nil, err } return ep, nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Construct the network object network := &network{ name: name, networkType: networkType, generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)}, ipamType: ipamapi.DefaultIPAM, id: stringid.GenerateRandomID(), ctrlr: c, persist: true, drvOnce: &sync.Once{}, } network.processOptions(options...) // Make sure we have a driver available for this network type // before we allocate anything. if _, err := network.driver(); err != nil { return nil, err } err := network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { network.ipamRelease() } }() if err = c.addNetwork(network); err != nil { return nil, err } defer func() { if err != nil { if e := network.deleteNetwork(); e != nil { log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) } } }() if err = c.updateToStore(network); err != nil { return nil, err } defer func() { if err != nil { if e := c.deleteFromStore(network); e != nil { log.Warnf("couldnt rollback from store, network %s on failure (%v): %v", network.name, err, e) } } }() network.epCnt = &endpointCnt{n: network} if err = c.updateToStore(network.epCnt); err != nil { return nil, err } return network, nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) { //验证网络的名称是否符合规范。 if !config.IsValidName(name) { return nil, ErrInvalidName(name) } // Construct the network object //创建网络的对象。在libnetwork/network.go中。 network := &network{ name: name, networkType: networkType, generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)}, ipamType: ipamapi.DefaultIPAM, id: stringid.GenerateRandomID(), ctrlr: c, persist: true, drvOnce: &sync.Once{}, } //分解配置。 network.processOptions(options...) // Make sure we have a driver available for this network type // before we allocate anything. //确定该driver确实存在。就是检查network中的controller的drivers是否含有该networktype。 if _, err := network.driver(true); err != nil { return nil, err } //预留本宿主机可以使用的ip地址池。 //周飒仔细研究。 err := network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { network.ipamRelease() } }() //增加给网络模式。 if err = c.addNetwork(network); err != nil { return nil, err } defer func() { if err != nil { if e := network.deleteNetwork(); e != nil { log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) } } }() // First store the endpoint count, then the network. To avoid to // end up with a datastore containing a network and not an epCnt, // in case of an ungraceful shutdown during this function call. epCnt := &endpointCnt{n: network} if err = c.updateToStore(epCnt); err != nil { return nil, err } defer func() { if err != nil { if e := c.deleteFromStore(epCnt); e != nil { log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e) } } }() network.epCnt = epCnt if err = c.updateToStore(network); err != nil { return nil, err } return network, nil }
// NewNetwork creates a new network of the specified network type. The options // are network specific and modeled in a generic way. func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) { if !config.IsValidName(name) { return nil, ErrInvalidName(name) } if id == "" { id = stringid.GenerateRandomID() } // Construct the network object network := &network{ name: name, networkType: networkType, generic: map[string]interface{}{netlabel.GenericData: make(map[string]string)}, ipamType: ipamapi.DefaultIPAM, id: id, ctrlr: c, persist: true, drvOnce: &sync.Once{}, } network.processOptions(options...) // Make sure we have a driver available for this network type // before we allocate anything. if _, err := network.driver(true); err != nil { return nil, err } err := network.ipamAllocate() if err != nil { return nil, err } defer func() { if err != nil { network.ipamRelease() } }() err = c.addNetwork(network) if err != nil { return nil, err } defer func() { if err != nil { if e := network.deleteNetwork(); e != nil { log.Warnf("couldn't roll back driver network on network %s creation failure: %v", network.name, err) } } }() // First store the endpoint count, then the network. To avoid to // end up with a datastore containing a network and not an epCnt, // in case of an ungraceful shutdown during this function call. epCnt := &endpointCnt{n: network} if err = c.updateToStore(epCnt); err != nil { return nil, err } defer func() { if err != nil { if e := c.deleteFromStore(epCnt); e != nil { log.Warnf("couldnt rollback from store, epCnt %v on failure (%v): %v", epCnt, err, e) } } }() network.epCnt = epCnt if err = c.updateToStore(network); err != nil { return nil, err } if err = network.joinCluster(); err != nil { log.Errorf("Failed to join network %s into agent cluster: %v", name, err) } network.addDriverWatches() return network, nil }