// RequestPool returns an address pool along with its unique id. func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) { log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6) k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6) if err != nil { return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err) } retry: if err := a.refresh(addressSpace); err != nil { return "", nil, nil, err } aSpace, err := a.getAddrSpace(addressSpace) if err != nil { return "", nil, nil, err } insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr) if err != nil { return "", nil, nil, err } if err := a.writeToStore(aSpace); err != nil { if _, ok := err.(types.RetryError); !ok { return "", nil, nil, types.InternalErrorf("pool configuration failed because of %s", err.Error()) } goto retry } return k.String(), nw, nil, insert() }
// Init registers a new instance of overlay driver func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { c := driverapi.Capability{ DataScope: datastore.GlobalScope, } d := &driver{ networks: networkTable{}, peerDb: peerNetworkMap{ mp: map[string]*peerMap{}, }, secMap: &encrMap{nodes: map[string][]*spi{}}, config: config, } if data, ok := config[netlabel.GlobalKVClient]; ok { var err error dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.store, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("failed to initialize data store: %v", err) } } return dc.RegisterDriver(networkType, d, c) }
func (ep *endpoint) UnmarshalJSON(b []byte) error { var ( err error epMap map[string]interface{} ) if err = json.Unmarshal(b, &epMap); err != nil { return fmt.Errorf("Failed to unmarshal to macvlan endpoint: %v", err) } if v, ok := epMap["MacAddress"]; ok { if ep.mac, err = net.ParseMAC(v.(string)); err != nil { return types.InternalErrorf("failed to decode macvlan endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) } } if v, ok := epMap["Addr"]; ok { if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode macvlan endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) } } if v, ok := epMap["Addrv6"]; ok { if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode macvlan endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) } } ep.id = epMap["id"].(string) ep.nid = epMap["nid"].(string) ep.srcName = epMap["SrcName"].(string) return nil }
func (ep *endpoint) UnmarshalJSON(value []byte) error { var ( err error epMap map[string]interface{} ) json.Unmarshal(value, &epMap) ep.id = epMap["id"].(string) ep.nid = epMap["nid"].(string) if v, ok := epMap["mac"]; ok { if ep.mac, err = net.ParseMAC(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string)) } } if v, ok := epMap["addr"]; ok { if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err) } } if v, ok := epMap["ifName"]; ok { ep.ifName = v.(string) } return nil }
func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { var ( err error nMap map[string]interface{} ) if err = json.Unmarshal(b, &nMap); err != nil { return err } if v, ok := nMap["AddressIPv4"]; ok { if ncfg.AddressIPv4, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode bridge network address IPv4 after json unmarshal: %s", v.(string)) } } if v, ok := nMap["AddressIPv6"]; ok { if ncfg.AddressIPv6, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode bridge network address IPv6 after json unmarshal: %s", v.(string)) } } ncfg.DefaultBindingIP = net.ParseIP(nMap["DefaultBindingIP"].(string)) ncfg.DefaultGatewayIPv4 = net.ParseIP(nMap["DefaultGatewayIPv4"].(string)) ncfg.DefaultGatewayIPv6 = net.ParseIP(nMap["DefaultGatewayIPv6"].(string)) ncfg.ID = nMap["ID"].(string) ncfg.BridgeName = nMap["BridgeName"].(string) ncfg.EnableIPv6 = nMap["EnableIPv6"].(bool) ncfg.EnableIPMasquerade = nMap["EnableIPMasquerade"].(bool) ncfg.EnableICC = nMap["EnableICC"].(bool) ncfg.Mtu = int(nMap["Mtu"].(float64)) return nil }
func (d *driver) initStore(option map[string]interface{}) error { if data, ok := option[netlabel.LocalKVClient]; ok { var err error dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.store, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("bridge driver failed to initialize data store: %v", err) } err = d.populateNetworks() if err != nil { return err } err = d.populateEndpoints() if err != nil { return err } } return nil }
// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error { switch dType { case discoverapi.NodeDiscovery: nodeData, ok := data.(discoverapi.NodeDiscoveryData) if !ok || nodeData.Address == "" { return fmt.Errorf("invalid discovery data") } d.nodeJoin(nodeData.Address, nodeData.Self) case discoverapi.DatastoreConfig: var err error if d.store != nil { return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already") } dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.store, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("failed to initialize data store: %v", err) } default: } return nil }
// DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error { var err error switch dType { case discoverapi.NodeDiscovery: nodeData, ok := data.(discoverapi.NodeDiscoveryData) if !ok || nodeData.Address == "" { return fmt.Errorf("invalid discovery data") } d.nodeJoin(nodeData.Address, nodeData.Self) case discoverapi.DatastoreConfig: if d.store != nil { return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already") } dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.store, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("failed to initialize data store: %v", err) } case discoverapi.EncryptionKeysConfig: encrData, ok := data.(discoverapi.DriverEncryptionConfig) if !ok { return fmt.Errorf("invalid encryption key notification data") } keys := make([]*key, 0, len(encrData.Keys)) for i := 0; i < len(encrData.Keys); i++ { k, err := parseEncryptionKey(encrData.Keys[i], encrData.Tags[i]) if err != nil { return err } keys = append(keys, k) } d.setKeys(keys) case discoverapi.EncryptionKeysUpdate: var newKey, delKey, priKey *key encrData, ok := data.(discoverapi.DriverEncryptionUpdate) if !ok { return fmt.Errorf("invalid encryption key notification data") } newKey, err = parseEncryptionKey(encrData.Key, encrData.Tag) if err != nil { return err } priKey, err = parseEncryptionKey(encrData.Primary, encrData.PrimaryTag) if err != nil { return err } delKey, err = parseEncryptionKey(encrData.Prune, encrData.PruneTag) if err != nil { return err } d.updateKeys(newKey, priKey, delKey) default: } return nil }
// ReleaseAddress releases the address from the specified pool ID func (a *Allocator) ReleaseAddress(poolID string, address net.IP) error { logrus.Debugf("ReleaseAddress(%s, %v)", poolID, address) k := SubnetKey{} if err := k.FromString(poolID); err != nil { return types.BadRequestErrorf("invalid pool id: %s", poolID) } if err := a.refresh(k.AddressSpace); err != nil { return err } aSpace, err := a.getAddrSpace(k.AddressSpace) if err != nil { return err } aSpace.Lock() p, ok := aSpace.subnets[k] if !ok { aSpace.Unlock() return types.NotFoundErrorf("cannot find address pool for poolID:%s", poolID) } if address == nil { aSpace.Unlock() return types.BadRequestErrorf("invalid address: nil") } if !p.Pool.Contains(address) { aSpace.Unlock() return ipamapi.ErrIPOutOfRange } c := p for c.Range != nil { k = c.ParentKey c = aSpace.subnets[k] } aSpace.Unlock() mask := p.Pool.Mask h, err := types.GetHostPartIP(address, mask) if err != nil { return types.InternalErrorf("failed to release address %s: %v", address.String(), err) } bm, err := a.retrieveBitmask(k, c.Pool) if err != nil { return types.InternalErrorf("could not find bitmask in datastore for %s on address %v release from pool %s: %v", k.String(), address, poolID, err) } return bm.Unset(ipToUint64(h)) }
func (epi *endpointInterface) UnmarshalJSON(b []byte) error { var ( err error epMap map[string]interface{} ) if err = json.Unmarshal(b, &epMap); err != nil { return err } if v, ok := epMap["mac"]; ok { if epi.mac, err = net.ParseMAC(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string)) } } if v, ok := epMap["addr"]; ok { if epi.addr, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err) } } if v, ok := epMap["addrv6"]; ok { if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err) } } epi.srcName = epMap["srcName"].(string) epi.dstPrefix = epMap["dstPrefix"].(string) rb, _ := json.Marshal(epMap["routes"]) var routes []string json.Unmarshal(rb, &routes) epi.routes = make([]*net.IPNet, 0) for _, route := range routes { ip, ipr, err := net.ParseCIDR(route) if err == nil { ipr.IP = ip epi.routes = append(epi.routes, ipr) } } epi.v4PoolID = epMap["v4PoolID"].(string) epi.v6PoolID = epMap["v6PoolID"].(string) al, _ := json.Marshal(epMap["ipAliases"]) // TODO check var aliases []string json.Unmarshal(al, &aliases) epi.ipAliases = make([]*net.IPNet, 0) for _, alias := range aliases { ip, err := types.ParseCIDR(alias) if err == nil { epi.ipAliases = append(epi.ipAliases, ip) } else { // TODO log error } } return nil }
// Init registers a new instance of overlay driver func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { c := driverapi.Capability{ DataScope: datastore.GlobalScope, } d := &driver{ networks: networkTable{}, peerDb: peerNetworkMap{ mp: map[string]*peerMap{}, }, secMap: &encrMap{nodes: map[string][]*spi{}}, config: config, } if data, ok := config[netlabel.GlobalKVClient]; ok { var err error dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.store, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("failed to initialize data store: %v", err) } } if data, ok := config[netlabel.LocalKVClient]; ok { var err error dsc, ok := data.(discoverapi.DatastoreConfigData) if !ok { return types.InternalErrorf("incorrect data in datastore configuration: %v", data) } d.localStore, err = datastore.NewDataStoreFromConfig(dsc) if err != nil { return types.InternalErrorf("failed to initialize local data store: %v", err) } } if err := d.restoreEndpoints(); err != nil { logrus.Warnf("Failure during overlay endpoints restore: %v", err) } // If an error happened when the network join the sandbox during the endpoints restore // we should reset it now along with the once variable, so that subsequent endpoint joins // outside of the restore path can potentially fix the network join and succeed. for nid, n := range d.networks { if n.initErr != nil { logrus.Infof("resetting init error and once variable for network %s after unsuccesful endpoint restore: %v", nid, n.initErr) n.initErr = nil n.once = &sync.Once{} } } return dc.RegisterDriver(networkType, d, c) }
func (epi *endpointInterface) UnmarshalJSON(b []byte) error { var ( err error epMap map[string]interface{} ) if err = json.Unmarshal(b, &epMap); err != nil { return err } if v, ok := epMap["mac"]; ok { if epi.mac, err = net.ParseMAC(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface mac address after json unmarshal: %s", v.(string)) } } if v, ok := epMap["addr"]; ok { if epi.addr, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface ipv4 address after json unmarshal: %v", err) } } if v, ok := epMap["addrv6"]; ok { if epi.addrv6, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode endpoint interface ipv6 address after json unmarshal: %v", err) } } if v, ok := epMap["llAddrs"]; ok { list := v.([]interface{}) epi.llAddrs = make([]*net.IPNet, 0, len(list)) for _, llS := range list { ll, err := types.ParseCIDR(llS.(string)) if err != nil { return types.InternalErrorf("failed to decode endpoint interface link-local address (%v) after json unmarshal: %v", llS, err) } epi.llAddrs = append(epi.llAddrs, ll) } } epi.srcName = epMap["srcName"].(string) epi.dstPrefix = epMap["dstPrefix"].(string) rb, _ := json.Marshal(epMap["routes"]) var routes []string json.Unmarshal(rb, &routes) epi.routes = make([]*net.IPNet, 0) for _, route := range routes { ip, ipr, err := net.ParseCIDR(route) if err == nil { ipr.IP = ip epi.routes = append(epi.routes, ipr) } } epi.v4PoolID = epMap["v4PoolID"].(string) epi.v6PoolID = epMap["v6PoolID"].(string) return nil }
// ReleasePool releases the address pool identified by the passed id func (a *Allocator) ReleasePool(poolID string) error { logrus.Debugf("ReleasePool(%s)", poolID) k := SubnetKey{} if err := k.FromString(poolID); err != nil { return types.BadRequestErrorf("invalid pool id: %s", poolID) } retry: if err := a.refresh(k.AddressSpace); err != nil { return err } aSpace, err := a.getAddrSpace(k.AddressSpace) if err != nil { return err } remove, err := aSpace.updatePoolDBOnRemoval(k) if err != nil { return err } if err = a.writeToStore(aSpace); err != nil { if _, ok := err.(types.RetryError); !ok { return types.InternalErrorf("pool (%s) removal failed because of %v", poolID, err) } goto retry } return remove() }
// ReleasePool releases the address pool identified by the passed id func (a *Allocator) ReleasePool(poolID string) error { k := SubnetKey{} if err := k.FromString(poolID); err != nil { return types.BadRequestErrorf("invalid pool id: %s", poolID) } cfg, err := a.getPoolsConfig(k.AddressSpace) if err != nil { return err } retry: remove, err := cfg.updatePoolDBOnRemoval(k) if err != nil { return err } if err = cfg.writeToStore(); err != nil { if _, ok := err.(types.RetryError); !ok { return types.InternalErrorf("pool (%s) removal failed because of %v", poolID, err) } if erru := cfg.readFromStore(); erru != nil { return fmt.Errorf("failed to get updated pool config from datastore (%v) after (%v)", erru, err) } goto retry } return remove() }
func (r *DrvRegistry) registerIpamDriver(name string, driver ipamapi.Ipam, caps *ipamapi.Capability) error { if strings.TrimSpace(name) == "" { return fmt.Errorf("ipam driver name string cannot be empty") } r.Lock() _, ok := r.ipamDrivers[name] r.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) } if r.ifn != nil { if err := r.ifn(name, driver, caps); err != nil { return err } } r.Lock() r.ipamDrivers[name] = &ipamData{driver: driver, defaultLocalAddressSpace: locAS, defaultGlobalAddressSpace: glbAS, capability: caps} r.Unlock() return nil }
// SetupDevice create a new bridge interface/ func setupDevice(config *networkConfiguration, i *bridgeInterface) error { // We only attempt to create the bridge when the requested device name is // the default one. if config.BridgeName != DefaultBridgeName && !config.AllowNonDefaultBridge { return NonDefaultBridgeExistError(config.BridgeName) } // Set the bridgeInterface netlink.Bridge. i.Link = &netlink.Bridge{ LinkAttrs: netlink.LinkAttrs{ Name: config.BridgeName, }, } // Only set the bridge's MAC address if the kernel version is > 3.3, as it // was not supported before that. kv, err := kernel.GetKernelVersion() if err == nil && (kv.Kernel >= 3 && kv.Major >= 3) { i.Link.Attrs().HardwareAddr = netutils.GenerateRandomMAC() log.Debugf("Setting bridge mac address to %s", i.Link.Attrs().HardwareAddr) } // Call out to netlink to create the device. if err = netlink.LinkAdd(i.Link); err != nil { return types.InternalErrorf("Failed to program bridge link: %s", err.Error()) } return nil }
// RequestPool returns an address pool along with its unique id. func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) { k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6) if err != nil { return "", nil, nil, ipamapi.ErrInvalidPool } retry: if err := a.refresh(addressSpace); err != nil { return "", nil, nil, err } aSpace, err := a.getAddrSpace(addressSpace) if err != nil { return "", nil, nil, err } insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr) if err != nil { return "", nil, nil, err } if err := a.writeToStore(aSpace); err != nil { if _, ok := err.(types.RetryError); !ok { return "", nil, nil, types.InternalErrorf("pool configuration failed because of %s", err.Error()) } goto retry } return k.String(), aw, nil, insert() }
func (n *network) addEndpoint(ep *endpoint) error { d, err := n.driver() if err != nil { return fmt.Errorf("failed to add endpoint: %v", err) } // If it is bridge network type make sure we call the driver about the network // because the network may have been created in some past life of libnetwork. if n.Type() == "bridge" { n.drvOnce.Do(func() { err = n.getController().addNetwork(n) }) if err != nil { return err } } err = d.CreateEndpoint(n.id, ep.id, ep.Interface(), ep.generic) if err != nil { return types.InternalErrorf("failed to create endpoint %s on network %s: %v", ep.Name(), n.Name(), err) } return nil }
func (aSpace *addrSpace) updatePoolDBOnRemoval(k SubnetKey) (func() error, error) { aSpace.Lock() defer aSpace.Unlock() p, ok := aSpace.subnets[k] if !ok { return nil, ipamapi.ErrBadPool } aSpace.incRefCount(p, -1) c := p for ok { if c.RefCount == 0 { delete(aSpace.subnets, k) if c.Range == nil { return func() error { bm, err := aSpace.alloc.retrieveBitmask(k, c.Pool) if err != nil { return types.InternalErrorf("could not find bitmask in datastore for pool %s removal: %v", k.String(), err) } return bm.Destroy() }, nil } } k = c.ParentKey c, ok = aSpace.subnets[k] } return func() error { return nil }, nil }
func (n *network) Delete() error { var err error n.Lock() ctrlr := n.ctrlr n.Unlock() ctrlr.Lock() _, ok := ctrlr.networks[n.id] ctrlr.Unlock() if !ok { return &UnknownNetworkError{name: n.name, id: string(n.id)} } numEps := n.EndpointCnt() if numEps != 0 { return &ActiveEndpointsError{name: n.name, id: string(n.id)} } // deleteNetworkFromStore performs an atomic delete operation and the network.endpointCnt field will help // prevent any possible race between endpoint join and network delete if err = ctrlr.deleteNetworkFromStore(n); err != nil { if err == datastore.ErrKeyModified { return types.InternalErrorf("operation in progress. delete failed for network %s. Please try again.") } return err } if err = n.deleteNetwork(); err != nil { return err } return nil }
// RequestPool returns an address pool along with its unique id. func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) { k, nw, aw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6) if err != nil { return "", nil, nil, ipamapi.ErrInvalidPool } cfg, err := a.getPoolsConfig(addressSpace) if err != nil { return "", nil, nil, err } retry: insert, err := cfg.updatePoolDBOnAdd(*k, nw, ipr) if err != nil { return "", nil, nil, err } if err := cfg.writeToStore(); err != nil { if _, ok := err.(types.RetryError); !ok { return "", nil, nil, types.InternalErrorf("pool configuration failed because of %s", err.Error()) } if erru := cfg.readFromStore(); erru != nil { return "", nil, nil, fmt.Errorf("failed to get updated pool config from datastore (%v) after (%v)", erru, err) } goto retry } return k.String(), aw, nil, insert() }
func (sb *sandbox) buildHostsFile() error { if sb.config.hostsPath == "" { sb.config.hostsPath = defaultPrefix + "/" + sb.id + "/hosts" } dir, _ := filepath.Split(sb.config.hostsPath) if err := createBasePath(dir); err != nil { return err } // This is for the host mode networking if sb.config.originHostsPath != "" { if err := copyFile(sb.config.originHostsPath, sb.config.hostsPath); err != nil && !os.IsNotExist(err) { return types.InternalErrorf("could not copy source hosts file %s to %s: %v", sb.config.originHostsPath, sb.config.hostsPath, err) } return nil } extraContent := make([]etchosts.Record, 0, len(sb.config.extraHosts)) for _, extraHost := range sb.config.extraHosts { extraContent = append(extraContent, etchosts.Record{Hosts: extraHost.name, IP: extraHost.IP}) } return etchosts.Build(sb.config.hostsPath, "", sb.config.hostName, sb.config.domainName, extraContent) }
func (ep *bridgeEndpoint) UnmarshalJSON(b []byte) error { var ( err error epMap map[string]interface{} ) if err = json.Unmarshal(b, &epMap); err != nil { return fmt.Errorf("Failed to unmarshal to bridge endpoint: %v", err) } if v, ok := epMap["MacAddress"]; ok { if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil { return types.InternalErrorf("failed to decode bridge endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) } } if v, ok := epMap["Addr"]; ok { if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode bridge endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) } } if v, ok := epMap["Addrv6"]; ok { if ep.addrv6, err = types.ParseCIDR(v.(string)); err != nil { return types.InternalErrorf("failed to decode bridge endpoint IPv6 address (%s) after json unmarshal: %v", v.(string), err) } } ep.id = epMap["id"].(string) ep.nid = epMap["nid"].(string) ep.srcName = epMap["SrcName"].(string) d, _ := json.Marshal(epMap["Config"]) if err := json.Unmarshal(d, &ep.config); err != nil { logrus.Warnf("Failed to decode endpoint config %v", err) } d, _ = json.Marshal(epMap["ContainerConfig"]) if err := json.Unmarshal(d, &ep.containerConfig); err != nil { logrus.Warnf("Failed to decode endpoint container config %v", err) } d, _ = json.Marshal(epMap["ExternalConnConfig"]) if err := json.Unmarshal(d, &ep.extConnConfig); err != nil { logrus.Warnf("Failed to decode endpoint external connectivity configuration %v", err) } d, _ = json.Marshal(epMap["PortMapping"]) if err := json.Unmarshal(d, &ep.portMapping); err != nil { logrus.Warnf("Failed to decode endpoint port mapping %v", err) } return nil }
// RequestPool returns an address pool along with its unique id. func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) { logrus.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6) k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6) if err != nil { return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err) } pdf := k == nil retry: if pdf { if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil { return "", nil, nil, err } k = &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String()} } if err := a.refresh(addressSpace); err != nil { return "", nil, nil, err } aSpace, err := a.getAddrSpace(addressSpace) if err != nil { return "", nil, nil, err } insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr, pdf) if err != nil { if _, ok := err.(types.MaskableError); ok { logrus.Debugf("Retrying predefined pool search: %v", err) goto retry } return "", nil, nil, err } if err := a.writeToStore(aSpace); err != nil { if _, ok := err.(types.RetryError); !ok { return "", nil, nil, types.InternalErrorf("pool configuration failed because of %s", err.Error()) } goto retry } return k.String(), nw, nil, insert() }
func (a *Allocator) deleteFromStore(aSpace *addrSpace) error { store := aSpace.store() if store == nil { return types.InternalErrorf("invalid store while trying to delete %s address space", aSpace.DataScope()) } return store.DeleteObjectAtomic(aSpace) }
func (a *Allocator) getAddressSpaceFromStore(as string) (*addrSpace, error) { store := a.getStore(as) if store == nil { return nil, types.InternalErrorf("store for address space %s not found", as) } pc := &addrSpace{id: dsConfigKey + "/" + as, ds: store, alloc: a} if err := store.GetObject(datastore.Key(pc.Key()...), pc); err != nil { if err == datastore.ErrKeyNotFound { return nil, nil } return nil, types.InternalErrorf("could not get pools config from store: %v", err) } return pc, nil }
func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error { var ( poolID *string address **net.IPNet prefAdd net.IP progAdd net.IP ) n := ep.getNetwork() switch ipVer { case 4: poolID = &ep.iface.v4PoolID address = &ep.iface.addr prefAdd = ep.prefAddress case 6: poolID = &ep.iface.v6PoolID address = &ep.iface.addrv6 prefAdd = ep.prefAddressV6 default: return types.InternalErrorf("incorrect ip version number passed: %d", ipVer) } ipInfo := n.getIPInfo(ipVer) // ipv6 address is not mandatory if len(ipInfo) == 0 && ipVer == 6 { return nil } // The address to program may be chosen by the user or by the network driver in one specific // case to support backward compatibility with `docker daemon --fixed-cidrv6` use case if prefAdd != nil { progAdd = prefAdd } else if *address != nil { progAdd = (*address).IP } for _, d := range ipInfo { if progAdd != nil && !d.Pool.Contains(progAdd) { continue } addr, _, err := ipam.RequestAddress(d.PoolID, progAdd, ep.ipamOptions) if err == nil { ep.Lock() *address = addr *poolID = d.PoolID ep.Unlock() return nil } if err != ipamapi.ErrNoAvailableIPs || progAdd != nil { return err } } if progAdd != nil { return types.BadRequestErrorf("Invalid address %s: It does not belong to any of this network's subnets", prefAdd) } return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID()) }
// RemoveSubnet removes the subnet from the specified address space func (a *Allocator) RemoveSubnet(addrSpace AddressSpace, subnet *net.IPNet) error { if addrSpace == "" { return ErrInvalidAddressSpace } if subnet == nil { return ErrInvalidSubnet } retry: // Look for the respective subnet configuration data // Remove it along with the internal subnets subKey := subnetKey{addrSpace, subnet.String(), ""} a.Lock() current, ok := a.subnets[subKey] a.Unlock() if !ok { return ErrSubnetNotFound } // Remove config and sync to datastore a.Lock() delete(a.subnets, subKey) a.Unlock() err := a.writeToStore() if err != nil { if _, ok := err.(types.RetryError); !ok { return types.InternalErrorf("subnet removal failed because of %s", err.Error()) } // Update to latest if erru := a.readFromStore(); erru != nil { // Restore and bail out a.Lock() a.subnets[subKey] = current a.Unlock() return fmt.Errorf("failed to get updated subnets config from datastore (%v) after (%v)", erru, err) } goto retry } // Get the list of smaller internal subnets subnetList, err := getInternalSubnets(subnet, a.internalHostSize) if err != nil { return err } for _, s := range subnetList { sk := subnetKey{addrSpace, subKey.subnet, s.String()} a.Lock() if bm, ok := a.addresses[sk]; ok { bm.Destroy() } delete(a.addresses, sk) a.Unlock() } return nil }
func (sb *sandbox) setupDNS() error { if sb.config.resolvConfPath == "" { sb.config.resolvConfPath = defaultPrefix + "/" + sb.id + "/resolv.conf" } sb.config.resolvConfHashFile = sb.config.resolvConfPath + ".hash" dir, _ := filepath.Split(sb.config.resolvConfPath) if err := createBasePath(dir); err != nil { return err } // This is for the host mode networking if sb.config.originResolvConfPath != "" { if err := copyFile(sb.config.originResolvConfPath, sb.config.resolvConfPath); err != nil { return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", sb.config.originResolvConfPath, sb.config.resolvConfPath, err) } return nil } resolvConf, err := resolvconf.Get() if err != nil { return err } dnsList := resolvconf.GetNameservers(resolvConf) dnsSearchList := resolvconf.GetSearchDomains(resolvConf) dnsOptionsList := resolvconf.GetOptions(resolvConf) if len(sb.config.dnsList) > 0 || len(sb.config.dnsSearchList) > 0 || len(dnsOptionsList) > 0 { if len(sb.config.dnsList) > 0 { dnsList = sb.config.dnsList } if len(sb.config.dnsSearchList) > 0 { dnsSearchList = sb.config.dnsSearchList } if len(sb.config.dnsOptionsList) > 0 { dnsOptionsList = sb.config.dnsOptionsList } } hash, err := resolvconf.Build(sb.config.resolvConfPath, dnsList, dnsSearchList, dnsOptionsList) if err != nil { return err } // write hash if err := ioutil.WriteFile(sb.config.resolvConfHashFile, []byte(hash), filePerm); err != nil { return types.InternalErrorf("failed to write resol.conf hash file when setting up dns for sandbox %s: %v", sb.ID(), err) } return nil }
func (n *network) Delete() error { n.Lock() c := n.ctrlr name := n.name id := n.id n.Unlock() n, err := c.getNetworkFromStore(id) if err != nil { return &UnknownNetworkError{name: name, id: id} } numEps := n.EndpointCnt() if numEps != 0 { return &ActiveEndpointsError{name: n.name, id: n.id} } if err = n.deleteNetwork(); err != nil { return err } defer func() { if err != nil { if e := c.addNetwork(n); e != nil { log.Warnf("failed to rollback deleteNetwork for network %s: %v", n.Name(), err) } } }() // deleteFromStore performs an atomic delete operation and the // network.endpointCnt field will help prevent any possible // race between endpoint join and network delete if err = n.getController().deleteFromStore(n); err != nil { if err == datastore.ErrKeyModified { return types.InternalErrorf("operation in progress. delete failed for network %s. Please try again.") } return err } defer func() { if err != nil { n.dbExists = false if e := n.getController().updateToStore(n); e != nil { log.Warnf("failed to recreate network in store %s : %v", n.name, e) } } }() n.ipamRelease() return nil }