mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Avoid persisting ipam data if it can be reconstructed
- Also restore older behavior where overlap check is not run when preferred pool is specified. Got broken by recent changes Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
parent
0de68331ab
commit
651f6ea0fa
7 changed files with 69 additions and 5 deletions
|
@ -200,6 +200,8 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
|
|||
c.cleanupLocalEndpoints()
|
||||
c.networkCleanup()
|
||||
|
||||
c.reservePools()
|
||||
|
||||
if err := c.startExternalKeyListener(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -546,6 +548,52 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
|
|||
return network, nil
|
||||
}
|
||||
|
||||
func (c *controller) reservePools() {
|
||||
networks, err := c.getNetworksForScope(datastore.LocalScope)
|
||||
if err != nil {
|
||||
log.Warnf("Could not retrieve networks from local store during ipam allocation for existing networks: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, n := range networks {
|
||||
if !doReplayPoolReserve(n) {
|
||||
continue
|
||||
}
|
||||
// Construct pseudo configs for the auto IP case
|
||||
autoIPv4 := (len(n.ipamV4Config) == 0 || (len(n.ipamV4Config) == 1 && n.ipamV4Config[0].PreferredPool == "")) && len(n.ipamV4Info) > 0
|
||||
autoIPv6 := (len(n.ipamV6Config) == 0 || (len(n.ipamV6Config) == 1 && n.ipamV6Config[0].PreferredPool == "")) && len(n.ipamV6Info) > 0
|
||||
if autoIPv4 {
|
||||
n.ipamV4Config = []*IpamConf{{PreferredPool: n.ipamV4Info[0].Pool.String()}}
|
||||
}
|
||||
if n.enableIPv6 && autoIPv6 {
|
||||
n.ipamV6Config = []*IpamConf{{PreferredPool: n.ipamV6Info[0].Pool.String()}}
|
||||
}
|
||||
// Account current network gateways
|
||||
for i, c := range n.ipamV4Config {
|
||||
if c.Gateway == "" && n.ipamV4Info[i].Gateway != nil {
|
||||
c.Gateway = n.ipamV4Info[i].Gateway.IP.String()
|
||||
}
|
||||
}
|
||||
for i, c := range n.ipamV6Config {
|
||||
if c.Gateway == "" && n.ipamV6Info[i].Gateway != nil {
|
||||
c.Gateway = n.ipamV6Info[i].Gateway.IP.String()
|
||||
}
|
||||
}
|
||||
if err := n.ipamAllocate(); err != nil {
|
||||
log.Warnf("Failed to allocate ipam pool(s) for network %q (%s): %v", n.Name(), n.ID(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doReplayPoolReserve(n *network) bool {
|
||||
_, caps, err := n.getController().getIPAMDriver(n.ipamType)
|
||||
if err != nil {
|
||||
log.Warnf("Failed to retrieve ipam driver for network %q (%s): %v", n.Name(), n.ID(), err)
|
||||
return false
|
||||
}
|
||||
return caps.RequiresRequestReplay
|
||||
}
|
||||
|
||||
func (c *controller) addNetwork(n *network) error {
|
||||
d, err := n.driver(true)
|
||||
if err != nil {
|
||||
|
|
|
@ -249,6 +249,7 @@ During registration, the remote driver will receive a POST message to the URL `/
|
|||
|
||||
{
|
||||
"RequiresMACAddress": bool
|
||||
"RequiresRequestReplay": bool
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,6 +264,10 @@ As of now libnetwork accepts the following capabilities:
|
|||
It is a boolean value which tells libnetwork whether the ipam driver needs to know the interface MAC address in order to properly process the `RequestAddress()` call.
|
||||
If true, on `CreateEndpoint()` request, libnetwork will generate a random MAC address for the endpoint (if an explicit MAC address was not already provided by the user) and pass it to `RequestAddress()` when requesting the IP address inside the options map. The key will be the `netlabel.MacAddress` constant: `"com.docker.network.endpoint.macaddress"`.
|
||||
|
||||
### RequiresRequestReplay
|
||||
|
||||
It is a boolean value which tells libnetwork whether the ipam driver needs to receive the replay of the `RequestPool()` and `RequestAddress()` requests on daemon reload. When libnetwork controller is initializing, it retrieves from local store the list of current local scope networks and, if this capability flag is set, it allows the IPAM driver to reconstruct the database of pools by replaying the `RequestPool()` requests for each pool and the `RequestAddress()` for each network gateway owned by the local networks. This can be useful to ipam drivers which decide not to persist the pools allocated to local scope networks.
|
||||
|
||||
|
||||
## Appendix
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ func (r *DrvRegistry) initIPAMs(lDs, gDs interface{}) error {
|
|||
remoteIpam.Init,
|
||||
nullIpam.Init,
|
||||
} {
|
||||
if err := fn(r, lDs, gDs); err != nil {
|
||||
if err := fn(r, nil, gDs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,5 +80,10 @@ type Ipam interface {
|
|||
|
||||
// Capability represents the requirements and capabilities of the IPAM driver
|
||||
type Capability struct {
|
||||
// Whether on address request, libnetwork must
|
||||
// specify the endpoint MAC address
|
||||
RequiresMACAddress bool
|
||||
// Whether of daemon start, libnetwork must replay the pool
|
||||
// request and the address request for current local networks
|
||||
RequiresRequestReplay bool
|
||||
}
|
||||
|
|
|
@ -37,5 +37,7 @@ func Init(ic ipamapi.Callback, l, g interface{}) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return ic.RegisterIpamDriver(ipamapi.DefaultIPAM, a)
|
||||
cps := &ipamapi.Capability{RequiresRequestReplay: true}
|
||||
|
||||
return ic.RegisterIpamDriverWithCapabilities(ipamapi.DefaultIPAM, a, cps)
|
||||
}
|
||||
|
|
|
@ -23,11 +23,15 @@ func (r *Response) GetError() string {
|
|||
type GetCapabilityResponse struct {
|
||||
Response
|
||||
RequiresMACAddress bool
|
||||
RequiresRequestReplay bool
|
||||
}
|
||||
|
||||
// ToCapability converts the capability response into the internal ipam driver capaility structure
|
||||
func (capRes GetCapabilityResponse) ToCapability() *ipamapi.Capability {
|
||||
return &ipamapi.Capability{RequiresMACAddress: capRes.RequiresMACAddress}
|
||||
return &ipamapi.Capability{
|
||||
RequiresMACAddress: capRes.RequiresMACAddress,
|
||||
RequiresRequestReplay: capRes.RequiresRequestReplay,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAddressSpacesResponse is the response to the ``get default address spaces`` request message
|
||||
|
|
|
@ -86,7 +86,7 @@ func TestGetCapabilities(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !caps.RequiresMACAddress {
|
||||
if !caps.RequiresMACAddress || caps.RequiresRequestReplay {
|
||||
t.Fatalf("Unexpected capability: %v", caps)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue