Vendor libnetwork

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
This commit is contained in:
Flavio Crisciani 2018-07-17 12:12:18 -07:00
parent e353e7e3f0
commit fc4ebe0b8b
No known key found for this signature in database
GPG Key ID: 28CAFCE754CF3A48
46 changed files with 260 additions and 233 deletions

View File

@ -3,7 +3,7 @@
# LIBNETWORK_COMMIT is used to build the docker-userland-proxy binary. When
# updating the binary version, consider updating github.com/docker/libnetwork
# in vendor.conf accordingly
LIBNETWORK_COMMIT=3ac297bc7fd0afec9051bbb47024c9bc1d75bf5b
LIBNETWORK_COMMIT=f30a35b091cc2a431ef9856c75c343f75bb5f2e2
install_proxy() {
case "$1" in

View File

@ -37,7 +37,7 @@ github.com/mitchellh/hashstructure 2bca23e0e452137f789efbc8610126fd8b94f73b
#get libnetwork packages
# When updating, also update LIBNETWORK_COMMIT in hack/dockerfile/install/proxy accordingly
github.com/docker/libnetwork d00ceed44cc447c77f25cdf5d59e83163bdcb4c9
github.com/docker/libnetwork f30a35b091cc2a431ef9856c75c343f75bb5f2e2
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80
github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec

View File

@ -15,6 +15,17 @@ There are many networking solutions available to suit a broad range of use-cases
```go
import (
"fmt"
"log"
"github.com/docker/docker/pkg/reexec"
"github.com/docker/libnetwork"
"github.com/docker/libnetwork/config"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/options"
)
func main() {
if reexec.Init() {
return

View File

@ -194,7 +194,7 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
func (c *controller) agentSetup(clusterProvider cluster.Provider) error {
agent := c.getAgent()
// If the agent is already present there is no need to try to initilize it again
// If the agent is already present there is no need to try to initialize it again
if agent != nil {
return nil
}

View File

@ -372,7 +372,7 @@ func (h *Handle) set(ordinal, start, end uint64, any bool, release bool, serial
h.Lock()
}
// Previous atomic push was succesfull. Save private copy to local copy
// Previous atomic push was successful. Save private copy to local copy
h.unselected = nh.unselected
h.head = nh.head
h.dbExists = nh.dbExists

View File

@ -121,7 +121,7 @@ type NetworkController interface {
// Stop network controller
Stop()
// ReloadCondfiguration updates the controller configuration
// ReloadConfiguration updates the controller configuration
ReloadConfiguration(cfgOptions ...config.Option) error
// SetClusterProvider sets cluster provider
@ -1107,6 +1107,8 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (S
sb.config.hostsPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/hosts")
sb.config.resolvConfPath = filepath.Join(c.cfg.Daemon.DataDir, "/network/files/resolv.conf")
sb.id = "ingress_sbox"
} else if sb.loadBalancerNID != "" {
sb.id = "lb_" + sb.loadBalancerNID
}
c.Unlock()

View File

@ -185,7 +185,7 @@ func Key(key ...string) string {
func ParseKey(key string) ([]string, error) {
chain := strings.Split(strings.Trim(key, "/"), "/")
// The key must atleast be equal to the rootChain in order to be considered as valid
// The key must at least be equal to the rootChain in order to be considered as valid
if len(chain) <= len(rootChain) || !reflect.DeepEqual(chain[0:len(rootChain)], rootChain) {
return nil, types.BadRequestErrorf("invalid Key : %s", key)
}
@ -589,7 +589,7 @@ func (ds *datastore) DeleteObject(kvObject KVObject) error {
defer ds.Unlock()
}
// cleaup the cache first
// cleanup the cache first
if ds.cache != nil {
// If persistent store is skipped, sequencing needs to
// happen in cache.
@ -645,7 +645,7 @@ func (ds *datastore) DeleteTree(kvObject KVObject) error {
defer ds.Unlock()
}
// cleaup the cache first
// cleanup the cache first
if ds.cache != nil {
// If persistent store is skipped, sequencing needs to
// happen in cache.

View File

@ -8,8 +8,8 @@ import (
)
var (
// ErrNotImplmented exported
ErrNotImplmented = errors.New("Functionality not implemented")
// ErrNotImplemented exported
ErrNotImplemented = errors.New("Functionality not implemented")
)
// MockData exported
@ -65,7 +65,7 @@ func (s *MockStore) Exists(key string) (bool, error) {
// List gets a range of values at "directory"
func (s *MockStore) List(prefix string) ([]*store.KVPair, error) {
return nil, ErrNotImplmented
return nil, ErrNotImplemented
}
// DeleteTree deletes a range of values at "directory"
@ -76,17 +76,17 @@ func (s *MockStore) DeleteTree(prefix string) error {
// Watch a single key for modifications
func (s *MockStore) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) {
return nil, ErrNotImplmented
return nil, ErrNotImplemented
}
// WatchTree triggers a watch on a range of values at "directory"
func (s *MockStore) WatchTree(prefix string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) {
return nil, ErrNotImplmented
return nil, ErrNotImplemented
}
// NewLock exposed
func (s *MockStore) NewLock(key string, options *store.LockOptions) (store.Locker, error) {
return nil, ErrNotImplmented
return nil, ErrNotImplemented
}
// AtomicPut put a value at "key" if the key has not been

View File

@ -9,7 +9,7 @@ import (
"sync/atomic"
stackdump "github.com/docker/docker/pkg/signal"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/internal/caller"
"github.com/sirupsen/logrus"
)
@ -127,7 +127,7 @@ func notImplemented(ctx interface{}, w http.ResponseWriter, r *http.Request) {
rsp := WrongCommand("not implemented", fmt.Sprintf("URL path: %s no method implemented check /help\n", r.URL.Path))
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("command not implemented done")
HTTPReply(w, rsp, json)
@ -138,7 +138,7 @@ func help(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("help done")
n, ok := ctx.(*Server)
@ -156,7 +156,7 @@ func ready(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("ready done")
HTTPReply(w, CommandSucceed(&StringCmd{Info: "OK"}), json)
}
@ -166,7 +166,7 @@ func stackTrace(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("stack trace")
path, err := stackdump.DumpStacks("/tmp/")

View File

@ -75,10 +75,10 @@ type Driver interface {
// DecodeTableEntry passes the driver a key, value pair from table it registered
// with libnetwork. Driver should return {object ID, map[string]string} tuple.
// If DecodeTableEntry is called for a table associated with NetworkObject or
// EndpointObject the return object ID should be the network id or endppoint id
// EndpointObject the return object ID should be the network id or endpoint id
// associated with that entry. map should have information about the object that
// can be presented to the user.
// For exampe: overlay driver returns the VTEP IP of the host that has the endpoint
// For example: overlay driver returns the VTEP IP of the host that has the endpoint
// which is shown in 'network inspect --verbose'
DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string)
@ -97,7 +97,7 @@ type NetworkInfo interface {
TableEventRegister(tableName string, objType ObjectType) error
}
// InterfaceInfo provides a go interface for drivers to retrive
// InterfaceInfo provides a go interface for drivers to retrieve
// network information to interface resources.
type InterfaceInfo interface {
// SetMacAddress allows the driver to set the mac address to the endpoint interface

View File

@ -104,7 +104,7 @@ type containerConfiguration struct {
ChildEndpoints []string
}
// cnnectivityConfiguration represents the user specified configuration regarding the external connectivity
// connectivityConfiguration represents the user specified configuration regarding the external connectivity
type connectivityConfiguration struct {
PortBindings []types.PortBinding
ExposedPorts []types.TransportPort

View File

@ -84,7 +84,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
}
v4gw, _, err := net.ParseCIDR(s.GwIP)
if err != nil {
return fmt.Errorf("gatway %s is not a valid ipv4 address: %v", s.GwIP, err)
return fmt.Errorf("gateway %s is not a valid ipv4 address: %v", s.GwIP, err)
}
err = jinfo.SetGateway(v4gw)
if err != nil {
@ -101,7 +101,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
}
v6gw, _, err := net.ParseCIDR(s.GwIP)
if err != nil {
return fmt.Errorf("gatway %s is not a valid ipv6 address: %v", s.GwIP, err)
return fmt.Errorf("gateway %s is not a valid ipv6 address: %v", s.GwIP, err)
}
err = jinfo.SetGatewayIPv6(v6gw)
if err != nil {

View File

@ -68,7 +68,7 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
err = d.storeUpdate(config)
if err != nil {
d.deleteNetwork(config.ID)
logrus.Debugf("encoutered an error rolling back a network create for %s : %v", config.ID, err)
logrus.Debugf("encountered an error rolling back a network create for %s : %v", config.ID, err)
return err
}
@ -92,7 +92,7 @@ func (d *driver) createNetwork(config *configuration) error {
return err
}
config.CreatedSlaveLink = true
// notify the user in logs they have limited comunicatins
// notify the user in logs they have limited communications
if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
config.Parent)

View File

@ -30,7 +30,7 @@ func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
// Get the link for the master index (Example: the docker host eth iface)
parentLink, err := ns.NlHandle().LinkByName(parent)
if err != nil {
return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, parent, err)
return "", fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", ipvlanType, parent, err)
}
// Create an ipvlan link
ipvlan := &netlink.IPVlan{
@ -169,7 +169,7 @@ func createDummyLink(dummyName, truncNetID string) error {
}
parentDummyLink, err := ns.NlHandle().LinkByName(dummyName)
if err != nil {
return fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", ipvlanType, dummyName, err)
return fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", ipvlanType, dummyName, err)
}
// bring the new netlink iface up
if err := ns.NlHandle().LinkSetUp(parentDummyLink); err != nil {

View File

@ -31,7 +31,7 @@ func (d *driver) deleteNetwork(nid string) {
d.Unlock()
}
// getNetworks Safely returns a slice of existng networks
// getNetworks Safely returns a slice of existing networks
func (d *driver) getNetworks() []*network {
d.Lock()
defer d.Unlock()

View File

@ -46,7 +46,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
}
v4gw, _, err := net.ParseCIDR(s.GwIP)
if err != nil {
return fmt.Errorf("gatway %s is not a valid ipv4 address: %v", s.GwIP, err)
return fmt.Errorf("gateway %s is not a valid ipv4 address: %v", s.GwIP, err)
}
err = jinfo.SetGateway(v4gw)
if err != nil {
@ -63,7 +63,7 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
}
v6gw, _, err := net.ParseCIDR(s.GwIP)
if err != nil {
return fmt.Errorf("gatway %s is not a valid ipv6 address: %v", s.GwIP, err)
return fmt.Errorf("gateway %s is not a valid ipv6 address: %v", s.GwIP, err)
}
err = jinfo.SetGatewayIPv6(v6gw)
if err != nil {

View File

@ -72,7 +72,7 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
err = d.storeUpdate(config)
if err != nil {
d.deleteNetwork(config.ID)
logrus.Debugf("encoutered an error rolling back a network create for %s : %v", config.ID, err)
logrus.Debugf("encountered an error rolling back a network create for %s : %v", config.ID, err)
return err
}
@ -96,7 +96,7 @@ func (d *driver) createNetwork(config *configuration) error {
return err
}
config.CreatedSlaveLink = true
// notify the user in logs they have limited comunicatins
// notify the user in logs they have limited communications
if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
config.Parent)

View File

@ -30,7 +30,7 @@ func createMacVlan(containerIfName, parent, macvlanMode string) (string, error)
// Get the link for the master index (Example: the docker host eth iface)
parentLink, err := ns.NlHandle().LinkByName(parent)
if err != nil {
return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, parent, err)
return "", fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", macvlanType, parent, err)
}
// Create a macvlan link
macvlan := &netlink.Macvlan{
@ -173,7 +173,7 @@ func createDummyLink(dummyName, truncNetID string) error {
}
parentDummyLink, err := ns.NlHandle().LinkByName(dummyName)
if err != nil {
return fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, dummyName, err)
return fmt.Errorf("error occurred looking up the %s parent iface %s error: %s", macvlanType, dummyName, err)
}
// bring the new netlink iface up
if err := ns.NlHandle().LinkSetUp(parentDummyLink); err != nil {

View File

@ -601,7 +601,7 @@ func (n *network) maxMTU() int {
mtu -= vxlanEncap
if n.secure {
// In case of encryption account for the
// esp packet espansion and padding
// esp packet expansion and padding
mtu -= pktExpansion
mtu -= (mtu % 4)
}

View File

@ -47,18 +47,10 @@ func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo,
return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
}
if err := n.joinSandbox(false); err != nil {
if err := n.joinSandbox(s, false, true); err != nil {
return fmt.Errorf("network sandbox join failed: %v", err)
}
if err := n.joinSubnetSandbox(s, false); err != nil {
return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
}
// joinSubnetSandbox gets called when an endpoint comes up on a new subnet in the
// overlay network. Hence the Endpoint count should be updated outside joinSubnetSandbox
n.incEndpointCount()
sbox := n.sandbox()
overlayIfName, containerIfName, err := createVethPair()

View File

@ -39,7 +39,7 @@ var (
type networkTable map[string]*network
type subnet struct {
once *sync.Once
sboxInit bool
vxlanName string
brName string
vni uint32
@ -63,7 +63,7 @@ type network struct {
endpoints endpointTable
driver *driver
joinCnt int
once *sync.Once
sboxInit bool
initEpoch int
initErr error
subnets []*subnet
@ -150,7 +150,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
id: id,
driver: d,
endpoints: endpointTable{},
once: &sync.Once{},
subnets: []*subnet{},
}
@ -193,7 +192,6 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d
s := &subnet{
subnetIP: ipd.Pool,
gwIP: ipd.Gateway,
once: &sync.Once{},
}
if len(vnis) != 0 {
@ -277,7 +275,7 @@ func (d *driver) DeleteNetwork(nid string) error {
logrus.Warnf("Failed to delete overlay endpoint %.7s from local store: %v", ep.id, err)
}
}
// flush the peerDB entries
doPeerFlush = true
delete(d.networks, nid)
@ -304,29 +302,54 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
return nil
}
func (n *network) incEndpointCount() {
n.Lock()
defer n.Unlock()
n.joinCnt++
}
func (n *network) joinSandbox(restore bool) error {
func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error {
// If there is a race between two go routines here only one will win
// the other will wait.
n.once.Do(func() {
// save the error status of initSandbox in n.initErr so that
// all the racing go routines are able to know the status.
networkOnce.Do(networkOnceInit)
n.Lock()
// If non-restore initialization occurred and was successful then
// tell the peerDB to initialize the sandbox with all the peers
// previously received from networkdb. But only do this after
// unlocking the network. Otherwise we could deadlock with
// on the peerDB channel while peerDB is waiting for the network lock.
var doInitPeerDB bool
defer func() {
n.Unlock()
if doInitPeerDB {
n.driver.initSandboxPeerDB(n.id)
}
}()
if !n.sboxInit {
n.initErr = n.initSandbox(restore)
})
doInitPeerDB = n.initErr == nil && !restore
// If there was an error, we cannot recover it
n.sboxInit = true
}
return n.initErr
}
if n.initErr != nil {
return fmt.Errorf("network sandbox join failed: %v", n.initErr)
}
func (n *network) joinSubnetSandbox(s *subnet, restore bool) error {
s.once.Do(func() {
s.initErr = n.initSubnetSandbox(s, restore)
})
return s.initErr
subnetErr := s.initErr
if !s.sboxInit {
subnetErr = n.initSubnetSandbox(s, restore)
// We can recover from these errors, but not on restore
if restore || subnetErr == nil {
s.initErr = subnetErr
s.sboxInit = true
}
}
if subnetErr != nil {
return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), subnetErr)
}
if incJoinCount {
n.joinCnt++
}
return nil
}
func (n *network) leaveSandbox() {
@ -337,15 +360,14 @@ func (n *network) leaveSandbox() {
return
}
// We are about to destroy sandbox since the container is leaving the network
// Reinitialize the once variable so that we will be able to trigger one time
// sandbox initialization(again) when another container joins subsequently.
n.once = &sync.Once{}
for _, s := range n.subnets {
s.once = &sync.Once{}
}
n.destroySandbox()
n.sboxInit = false
n.initErr = nil
for _, s := range n.subnets {
s.sboxInit = false
s.initErr = nil
}
}
// to be called while holding network lock
@ -478,7 +500,7 @@ func (n *network) generateVxlanName(s *subnet) string {
id = n.id[:5]
}
return "vx-" + fmt.Sprintf("%06x", n.vxlanID(s)) + "-" + id
return fmt.Sprintf("vx-%06x-%v", s.vni, id)
}
func (n *network) generateBridgeName(s *subnet) string {
@ -491,7 +513,7 @@ func (n *network) generateBridgeName(s *subnet) string {
}
func (n *network) getBridgeNamePrefix(s *subnet) string {
return "ov-" + fmt.Sprintf("%06x", n.vxlanID(s))
return fmt.Sprintf("ov-%06x", s.vni)
}
func checkOverlap(nw *net.IPNet) error {
@ -513,7 +535,7 @@ func checkOverlap(nw *net.IPNet) error {
}
func (n *network) restoreSubnetSandbox(s *subnet, brName, vxlanName string) error {
sbox := n.sandbox()
sbox := n.sbox
// restore overlay osl sandbox
Ifaces := make(map[string][]osl.IfaceOption)
@ -542,7 +564,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
deleteInterfaceBySubnet(n.getBridgeNamePrefix(s), s)
}
// Try to delete the vxlan interface by vni if already present
deleteVxlanByVNI("", n.vxlanID(s))
deleteVxlanByVNI("", s.vni)
if err := checkOverlap(s.subnetIP); err != nil {
return err
@ -556,24 +578,24 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
// it must a stale namespace from previous
// life. Destroy it completely and reclaim resourced.
networkMu.Lock()
path, ok := vniTbl[n.vxlanID(s)]
path, ok := vniTbl[s.vni]
networkMu.Unlock()
if ok {
deleteVxlanByVNI(path, n.vxlanID(s))
deleteVxlanByVNI(path, s.vni)
if err := syscall.Unmount(path, syscall.MNT_FORCE); err != nil {
logrus.Errorf("unmount of %s failed: %v", path, err)
}
os.Remove(path)
networkMu.Lock()
delete(vniTbl, n.vxlanID(s))
delete(vniTbl, s.vni)
networkMu.Unlock()
}
}
// create a bridge and vxlan device for this subnet and move it to the sandbox
sbox := n.sandbox()
sbox := n.sbox
if err := sbox.AddInterface(brName, "br",
sbox.InterfaceOptions().Address(s.gwIP),
@ -581,13 +603,30 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
return fmt.Errorf("bridge creation in sandbox failed for subnet %q: %v", s.subnetIP.String(), err)
}
err := createVxlan(vxlanName, n.vxlanID(s), n.maxMTU())
err := createVxlan(vxlanName, s.vni, n.maxMTU())
if err != nil {
return err
}
if err := sbox.AddInterface(vxlanName, "vxlan",
sbox.InterfaceOptions().Master(brName)); err != nil {
// If adding vxlan device to the overlay namespace fails, remove the bridge interface we
// already added to the namespace. This allows the caller to try the setup again.
for _, iface := range sbox.Info().Interfaces() {
if iface.SrcName() == brName {
if ierr := iface.Remove(); ierr != nil {
logrus.Errorf("removing bridge failed from ov ns %v failed, %v", n.sbox.Key(), ierr)
}
}
}
// Also, delete the vxlan interface. Since a global vni id is associated
// with the vxlan interface, an orphaned vxlan interface will result in
// failure of vxlan device creation if the vni is assigned to some other
// network.
if deleteErr := deleteInterface(vxlanName); deleteErr != nil {
logrus.Warnf("could not delete vxlan interface, %s, error %v, after config error, %v", vxlanName, deleteErr, err)
}
return fmt.Errorf("vxlan interface creation failed for subnet %q: %v", s.subnetIP.String(), err)
}
@ -619,6 +658,7 @@ func (n *network) setupSubnetSandbox(s *subnet, brName, vxlanName string) error
return nil
}
// Must be called with the network lock
func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
brName := n.generateBridgeName(s)
vxlanName := n.generateVxlanName(s)
@ -633,10 +673,8 @@ func (n *network) initSubnetSandbox(s *subnet, restore bool) error {
}
}
n.Lock()
s.vxlanName = vxlanName
s.brName = brName
n.Unlock()
return nil
}
@ -677,11 +715,7 @@ func (n *network) cleanupStaleSandboxes() {
}
func (n *network) initSandbox(restore bool) error {
n.Lock()
n.initEpoch++
n.Unlock()
networkOnce.Do(networkOnceInit)
if !restore {
if hostMode {
@ -711,12 +745,7 @@ func (n *network) initSandbox(restore bool) error {
}
// this is needed to let the peerAdd configure the sandbox
n.setSandbox(sbox)
if !restore {
// Initialize the sandbox with all the peers previously received from networkdb
n.driver.initSandboxPeerDB(n.id)
}
n.sbox = sbox
// If we are in swarm mode, we don't need anymore the watchMiss routine.
// This will save 1 thread and 1 netlink socket per network
@ -734,7 +763,7 @@ func (n *network) initSandbox(restore bool) error {
tv := syscall.NsecToTimeval(soTimeout.Nanoseconds())
err = nlSock.SetReceiveTimeout(&tv)
})
n.setNetlinkSocket(nlSock)
n.nlSocket = nlSock
if err == nil {
go n.watchMiss(nlSock, key)
@ -836,7 +865,6 @@ func (d *driver) restoreNetworkFromStore(nid string) *network {
if n != nil {
n.driver = d
n.endpoints = endpointTable{}
n.once = &sync.Once{}
d.networks[nid] = n
}
return n
@ -844,11 +872,11 @@ func (d *driver) restoreNetworkFromStore(nid string) *network {
func (d *driver) network(nid string) *network {
d.Lock()
defer d.Unlock()
n, ok := d.networks[nid]
if !ok {
n = d.restoreNetworkFromStore(nid)
}
d.Unlock()
return n
}
@ -869,26 +897,12 @@ func (d *driver) getNetworkFromStore(nid string) *network {
func (n *network) sandbox() osl.Sandbox {
n.Lock()
defer n.Unlock()
return n.sbox
}
func (n *network) setSandbox(sbox osl.Sandbox) {
n.Lock()
n.sbox = sbox
n.Unlock()
}
func (n *network) setNetlinkSocket(nlSk *nl.NetlinkSocket) {
n.Lock()
n.nlSocket = nlSk
n.Unlock()
}
func (n *network) vxlanID(s *subnet) uint32 {
n.Lock()
defer n.Unlock()
return s.vni
}
@ -997,7 +1011,6 @@ func (n *network) SetValue(value []byte) error {
subnetIP: subnetIP,
gwIP: gwIP,
vni: vni,
once: &sync.Once{},
}
n.subnets = append(n.subnets, s)
} else {
@ -1023,7 +1036,10 @@ func (n *network) writeToStore() error {
}
func (n *network) releaseVxlanID() ([]uint32, error) {
if len(n.subnets) == 0 {
n.Lock()
nSubnets := len(n.subnets)
n.Unlock()
if nSubnets == 0 {
return nil, nil
}
@ -1039,14 +1055,17 @@ func (n *network) releaseVxlanID() ([]uint32, error) {
}
}
var vnis []uint32
n.Lock()
for _, s := range n.subnets {
if n.driver.vxlanIdm != nil {
vni := n.vxlanID(s)
vnis = append(vnis, vni)
n.driver.vxlanIdm.Release(uint64(vni))
vnis = append(vnis, s.vni)
}
s.vni = 0
}
n.Unlock()
n.setVxlanID(s, 0)
for _, vni := range vnis {
n.driver.vxlanIdm.Release(uint64(vni))
}
return vnis, nil
@ -1054,7 +1073,7 @@ func (n *network) releaseVxlanID() ([]uint32, error) {
func (n *network) obtainVxlanID(s *subnet) error {
//return if the subnet already has a vxlan id assigned
if s.vni != 0 {
if n.vxlanID(s) != 0 {
return nil
}
@ -1067,7 +1086,7 @@ func (n *network) obtainVxlanID(s *subnet) error {
return fmt.Errorf("getting network %q from datastore failed %v", n.id, err)
}
if s.vni == 0 {
if n.vxlanID(s) == 0 {
vxlanID, err := n.driver.vxlanIdm.GetID(true)
if err != nil {
return fmt.Errorf("failed to allocate vxlan id: %v", err)

View File

@ -105,17 +105,6 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
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 unsuccessful endpoint restore: %v", nid, n.initErr)
n.initErr = nil
n.once = &sync.Once{}
}
}
return dc.RegisterDriver(networkType, d, c)
}
@ -151,14 +140,10 @@ func (d *driver) restoreEndpoints() error {
return fmt.Errorf("could not find subnet for endpoint %s", ep.id)
}
if err := n.joinSandbox(true); err != nil {
if err := n.joinSandbox(s, true, true); err != nil {
return fmt.Errorf("restore network sandbox failed: %v", err)
}
if err := n.joinSubnetSandbox(s, true); err != nil {
return fmt.Errorf("restore subnet sandbox failed for %q: %v", s.subnetIP.String(), err)
}
Ifaces := make(map[string][]osl.IfaceOption)
vethIfaceOption := make([]osl.IfaceOption, 1)
vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
@ -166,10 +151,10 @@ func (d *driver) restoreEndpoints() error {
err := n.sbox.Restore(Ifaces, nil, nil, nil)
if err != nil {
n.leaveSandbox()
return fmt.Errorf("failed to restore overlay sandbox: %v", err)
}
n.incEndpointCount()
d.peerAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), false, false, true)
}
return nil

View File

@ -7,7 +7,8 @@ import (
"sync"
"syscall"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/internal/caller"
"github.com/docker/libnetwork/internal/setmatrix"
"github.com/docker/libnetwork/osl"
"github.com/sirupsen/logrus"
)
@ -59,7 +60,7 @@ func (p *peerEntryDB) UnMarshalDB() peerEntry {
type peerMap struct {
// set of peerEntry, note they have to be objects and not pointers to maintain the proper equality checks
mp common.SetMatrix
mp setmatrix.SetMatrix
sync.Mutex
}
@ -170,7 +171,7 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
pMap, ok := d.peerDb.mp[nid]
if !ok {
d.peerDb.mp[nid] = &peerMap{
mp: common.NewSetMatrix(),
mp: setmatrix.NewSetMatrix(),
}
pMap = d.peerDb.mp[nid]
@ -297,7 +298,7 @@ func (d *driver) peerOpRoutine(ctx context.Context, ch chan *peerOperation) {
}
func (d *driver) peerInit(nid string) {
callerName := common.CallerName(1)
callerName := caller.Name(1)
d.peerOpCh <- &peerOperation{
opType: peerOperationINIT,
networkID: nid,
@ -331,7 +332,7 @@ func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
l2Miss: l2Miss,
l3Miss: l3Miss,
localPeer: localPeer,
callerName: common.CallerName(1),
callerName: caller.Name(1),
}
}
@ -384,7 +385,7 @@ func (d *driver) peerAddOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
return fmt.Errorf("couldn't get vxlan id for %q: %v", s.subnetIP.String(), err)
}
if err := n.joinSubnetSandbox(s, false); err != nil {
if err := n.joinSandbox(s, false, false); err != nil {
return fmt.Errorf("subnet sandbox join failed for %q: %v", s.subnetIP.String(), err)
}
@ -422,7 +423,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
peerIPMask: peerIPMask,
peerMac: peerMac,
vtepIP: vtep,
callerName: common.CallerName(1),
callerName: caller.Name(1),
localPeer: localPeer,
}
}
@ -491,7 +492,7 @@ func (d *driver) peerFlush(nid string) {
d.peerOpCh <- &peerOperation{
opType: peerOperationFLUSH,
networkID: nid,
callerName: common.CallerName(1),
callerName: caller.Name(1),
}
}

View File

@ -150,7 +150,7 @@ type JoinRequest struct {
Options map[string]interface{}
}
// InterfaceName is the struct represetation of a pair of devices with source
// InterfaceName is the struct representation of a pair of devices with source
// and destination, for the purposes of putting an endpoint into a container.
type InterfaceName struct {
SrcName string

View File

@ -54,7 +54,7 @@ type IPAMNotifyFunc func(name string, driver ipamapi.Ipam, cap *ipamapi.Capabili
// DriverNotifyFunc defines the notify function signature when a new network driver gets registered.
type DriverNotifyFunc func(name string, driver driverapi.Driver, capability driverapi.Capability) error
// New retruns a new driver registry handle.
// New returns a new driver registry handle.
func New(lDs, gDs interface{}, dfn DriverNotifyFunc, ifn IPAMNotifyFunc, pg plugingetter.PluginGetter) (*DrvRegistry, error) {
r := &DrvRegistry{
drivers: make(driverTable),

View File

@ -1,4 +1,4 @@
package common
package caller
import (
"runtime"
@ -11,7 +11,7 @@ func callerInfo(i int) string {
if ok {
f := runtime.FuncForPC(ptr)
if f != nil {
// f.Name() is like: github.com/docker/libnetwork/common.MethodName
// f.Name() is like: github.com/docker/libnetwork/caller.MethodName
tmp := strings.Split(f.Name(), ".")
if len(tmp) > 0 {
fName = tmp[len(tmp)-1]
@ -22,8 +22,8 @@ func callerInfo(i int) string {
return fName
}
// CallerName returns the name of the function at the specified level
// Name returns the name of the function at the specified level
// level == 0 means current method name
func CallerName(level int) string {
func Name(level int) string {
return callerInfo(2 + level)
}

View File

@ -1,4 +1,4 @@
package common
package setmatrix
import (
"sync"

View File

@ -66,7 +66,7 @@ func newConnection() (*Conn, error) {
return c, nil
}
// Innitialize D-Bus connection.
// Initialize D-Bus connection.
func (c *Conn) initConnection() error {
var err error

View File

@ -477,7 +477,7 @@ func raw(args ...string) ([]byte, error) {
return filterOutput(startTime, output, args...), err
}
// RawCombinedOutput inernally calls the Raw function and returns a non nil
// RawCombinedOutput internally calls the Raw function and returns a non nil
// error if Raw returned a non nil error or a non empty output
func RawCombinedOutput(args ...string) error {
if output, err := Raw(args...); err != nil || len(output) != 0 {

View File

@ -100,7 +100,7 @@ func fillService(s *Service) nl.NetlinkRequestData {
return cmdAttr
}
func fillDestinaton(d *Destination) nl.NetlinkRequestData {
func fillDestination(d *Destination) nl.NetlinkRequestData {
cmdAttr := nl.NewRtAttr(ipvsCmdAttrDest, nil)
nl.NewRtAttrChild(cmdAttr, ipvsDestAttrAddress, rawIPData(d.Address))
@ -134,7 +134,7 @@ func (i *Handle) doCmdwithResponse(s *Service, d *Destination, cmd uint8) ([][]b
}
} else {
req.AddData(fillDestinaton(d))
req.AddData(fillDestination(d))
}
res, err := execute(i.sock, req, 0)

View File

@ -9,11 +9,11 @@ import (
"time"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/config"
"github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/etchosts"
"github.com/docker/libnetwork/internal/setmatrix"
"github.com/docker/libnetwork/ipamapi"
"github.com/docker/libnetwork/netlabel"
"github.com/docker/libnetwork/netutils"
@ -88,7 +88,7 @@ type NetworkInfo interface {
type EndpointWalker func(ep Endpoint) bool
// ipInfo is the reverse mapping from IP to service name to serve the PTR query.
// extResolver is set if an externl server resolves a service name to this IP.
// extResolver is set if an external server resolves a service name to this IP.
// Its an indication to defer PTR queries also to that external server.
type ipInfo struct {
name string
@ -104,9 +104,9 @@ type svcMapEntry struct {
}
type svcInfo struct {
svcMap common.SetMatrix
svcIPv6Map common.SetMatrix
ipMap common.SetMatrix
svcMap setmatrix.SetMatrix
svcIPv6Map setmatrix.SetMatrix
ipMap setmatrix.SetMatrix
service map[string][]servicePorts
}
@ -1353,7 +1353,7 @@ func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool
}
}
func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
func addIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
reverseIP := netutils.ReverseIP(ip.String())
ipMap.Insert(reverseIP, ipInfo{
name: name,
@ -1361,7 +1361,7 @@ func addIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
})
}
func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
func delIPToName(ipMap setmatrix.SetMatrix, name, serviceID string, ip net.IP) {
reverseIP := netutils.ReverseIP(ip.String())
ipMap.Remove(reverseIP, ipInfo{
name: name,
@ -1369,14 +1369,14 @@ func delIPToName(ipMap common.SetMatrix, name, serviceID string, ip net.IP) {
})
}
func addNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
func addNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
svcMap.Insert(name, svcMapEntry{
ip: epIP.String(),
serviceID: serviceID,
})
}
func delNameToIP(svcMap common.SetMatrix, name, serviceID string, epIP net.IP) {
func delNameToIP(svcMap setmatrix.SetMatrix, name, serviceID string, epIP net.IP) {
svcMap.Remove(name, svcMapEntry{
ip: epIP.String(),
serviceID: serviceID,
@ -1399,9 +1399,9 @@ func (n *network) addSvcRecords(eID, name, serviceID string, epIP, epIPv6 net.IP
sr, ok := c.svcRecords[n.ID()]
if !ok {
sr = svcInfo{
svcMap: common.NewSetMatrix(),
svcIPv6Map: common.NewSetMatrix(),
ipMap: common.NewSetMatrix(),
svcMap: setmatrix.NewSetMatrix(),
svcIPv6Map: setmatrix.NewSetMatrix(),
ipMap: setmatrix.NewSetMatrix(),
}
c.svcRecords[n.ID()] = sr
}
@ -1654,7 +1654,7 @@ func (n *network) ipamAllocateVersion(ipVer int, ipam ipamapi.Ipam) error {
return types.BadRequestErrorf("non parsable secondary ip address (%s:%s) passed for network %s", k, v, n.Name())
}
if !d.Pool.Contains(ip) {
return types.ForbiddenErrorf("auxilairy address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
return types.ForbiddenErrorf("auxiliary address: (%s:%s) must belong to the master pool: %s", k, v, d.Pool)
}
// Attempt reservation in the container addressable pool, silent the error if address does not belong to that pool
if d.IPAMData.AuxAddresses[k], _, err = ipam.RequestAddress(d.PoolID, ip, nil); err != nil && err != ipamapi.ErrIPOutOfRange {
@ -2036,7 +2036,7 @@ func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) {
logrus.Debugf("Service name To resolve: %v", name)
// There are DNS implementaions that allow SRV queries for names not in
// There are DNS implementations that allow SRV queries for names not in
// the format defined by RFC 2782. Hence specific validations checks are
// not done
parts := strings.Split(name, ".")
@ -2126,7 +2126,7 @@ func (n *network) lbEndpointName() string {
func (n *network) createLoadBalancerSandbox() (retErr error) {
sandboxName := n.lbSandboxName()
// Mark the sandbox to be a load balancer
sbOptions := []SandboxOption{OptionLoadBalancer()}
sbOptions := []SandboxOption{OptionLoadBalancer(n.id)}
if n.ingress {
sbOptions = append(sbOptions, OptionIngress())
}

View File

@ -243,7 +243,7 @@ func (nDB *NetworkDB) clusterLeave() error {
}
func (nDB *NetworkDB) triggerFunc(stagger time.Duration, C <-chan time.Time, f func()) {
// Use a random stagger to avoid syncronizing
// Use a random stagger to avoid synchronizing
randStagger := time.Duration(uint64(rnd.Int63()) % uint64(stagger))
select {
case <-time.After(randStagger):

View File

@ -58,7 +58,7 @@ type NetworkDB struct {
// List of all peer nodes which have left
leftNodes map[string]*node
// A multi-dimensional map of network/node attachmemts. The
// A multi-dimensional map of network/node attachments. The
// first key is a node name and the second key is a network ID
// for the network that node is participating in.
networks map[string]map[string]*network
@ -153,7 +153,7 @@ type network struct {
entriesNumber int
}
// Config represents the configuration of the networdb instance and
// Config represents the configuration of the networkdb instance and
// can be passed by the caller.
type Config struct {
// NodeID is the node unique identifier of the node when is part of the cluster

View File

@ -48,7 +48,7 @@ type MessageType int32
const (
MessageTypeInvalid MessageType = 0
// NetworEvent message type is used to communicate network
// NetworkEvent message type is used to communicate network
// attachments on the node.
MessageTypeNetworkEvent MessageType = 1
// TableEvent message type is used to communicate any table
@ -66,7 +66,7 @@ const (
// which is a pack of many message of above types, packed into
// a single compound message.
MessageTypeCompound MessageType = 5
// NodeEvent message type is used to communicare node
// NodeEvent message type is used to communicate node
// join/leave events in the cluster
MessageTypeNodeEvent MessageType = 6
)

View File

@ -19,7 +19,7 @@ enum MessageType {
INVALID = 0 [(gogoproto.enumvalue_customname) = "MessageTypeInvalid"];
// NetworEvent message type is used to communicate network
// NetworkEvent message type is used to communicate network
// attachments on the node.
NETWORK_EVENT = 1 [(gogoproto.enumvalue_customname) = "MessageTypeNetworkEvent"];
@ -42,7 +42,7 @@ enum MessageType {
// a single compound message.
COMPOUND = 5 [(gogoproto.enumvalue_customname) = "MessageTypeCompound"];
// NodeEvent message type is used to communicare node
// NodeEvent message type is used to communicate node
// join/leave events in the cluster
NODE_EVENT = 6 [(gogoproto.enumvalue_customname) = "MessageTypeNodeEvent"];
}

View File

@ -6,8 +6,8 @@ import (
"net/http"
"strings"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/diagnostic"
"github.com/docker/libnetwork/internal/caller"
"github.com/sirupsen/logrus"
)
@ -37,7 +37,7 @@ func dbJoin(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("join cluster")
if len(r.Form["members"]) < 1 {
@ -70,7 +70,7 @@ func dbPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("network peers")
if len(r.Form["nid"]) < 1 {
@ -104,7 +104,7 @@ func dbClusterPeers(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("cluster peers")
nDB, ok := ctx.(*NetworkDB)
@ -127,7 +127,7 @@ func dbCreateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("create entry")
if len(r.Form["tname"]) < 1 ||
@ -176,7 +176,7 @@ func dbUpdateEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("update entry")
if len(r.Form["tname"]) < 1 ||
@ -224,7 +224,7 @@ func dbDeleteEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("delete entry")
if len(r.Form["tname"]) < 1 ||
@ -261,7 +261,7 @@ func dbGetEntry(ctx interface{}, w http.ResponseWriter, r *http.Request) {
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("get entry")
if len(r.Form["tname"]) < 1 ||
@ -307,7 +307,7 @@ func dbJoinNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("join network")
if len(r.Form["nid"]) < 1 {
@ -339,7 +339,7 @@ func dbLeaveNetwork(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("leave network")
if len(r.Form["nid"]) < 1 {
@ -371,7 +371,7 @@ func dbGetTable(ctx interface{}, w http.ResponseWriter, r *http.Request) {
unsafe, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("get table")
if len(r.Form["tname"]) < 1 ||
@ -419,7 +419,7 @@ func dbNetworkStats(ctx interface{}, w http.ResponseWriter, r *http.Request) {
_, json := diagnostic.ParseHTTPFormOptions(r)
// audit logs
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": common.CallerName(0), "url": r.URL.String()})
log := logrus.WithFields(logrus.Fields{"component": "diagnostic", "remoteIP": r.RemoteAddr, "method": caller.Name(0), "url": r.URL.String()})
log.Info("network stats")
if len(r.Form["nid"]) < 1 {

View File

@ -289,6 +289,16 @@ func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...If
// Configure the interface now this is moved in the proper namespace.
if err := configureInterface(nlh, iface, i); err != nil {
// If configuring the device fails move it back to the host namespace
// and change the name back to the source name. This allows the caller
// to properly cleanup the interface. Its important especially for
// interfaces with global attributes, ex: vni id for vxlan interfaces.
if nerr := nlh.LinkSetName(iface, i.SrcName()); nerr != nil {
logrus.Errorf("renaming interface (%s->%s) failed, %v after config error %v", i.DstName(), i.SrcName(), nerr, err)
}
if nerr := nlh.LinkSetNsFd(iface, ns.ParseHandlerInt()); nerr != nil {
logrus.Errorf("moving inteface %s to host ns failed, %v, after config error %v", i.SrcName(), nerr, err)
}
return err
}

View File

@ -2,7 +2,7 @@ package kernel
type conditionalCheck func(val1, val2 string) bool
// OSValue represents a tuple, value defired, check function when to apply the value
// OSValue represents a tuple, value defined, check function when to apply the value
type OSValue struct {
Value string
CheckFn conditionalCheck

View File

@ -394,10 +394,13 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
// InitOSContext initializes OS context while configuring network resources
func InitOSContext() func() {
runtime.LockOSThread()
if err := ns.SetNamespace(); err != nil {
logrus.Error(err)
}
return runtime.UnlockOSThread
}
func nsInvoke(path string, prefunc, postfunc func(int) error) error {
func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error {
defer InitOSContext()()
newNs, err := netns.GetFromPath(path)
@ -412,14 +415,10 @@ func nsInvoke(path string, prefunc, postfunc func(int) error) error {
return fmt.Errorf("failed in prefunc: %v", err)
}
// save the current namespace (host namespace)
curNs, _ := netns.Get()
if err = netns.Set(newNs); err != nil {
return err
}
defer curNs.Close()
// will restore the previous namespace before unlocking the thread
defer netns.Set(curNs)
defer ns.SetNamespace()
// Invoked after the namespace switch.
return postfunc(ns.ParseHandlerInt())
@ -652,10 +651,7 @@ func (n *networkNamespace) ApplyOSTweaks(types []SandboxType) {
for _, t := range types {
switch t {
case SandboxTypeLoadBalancer:
nsInvoke(n.nsPath(),
func(nsFD int) error { return nil },
func(callerFD int) error { kernel.ApplyOSTweaks(loadBalancerConfig); return nil },
)
kernel.ApplyOSTweaks(loadBalancerConfig)
}
}
}

View File

@ -14,6 +14,11 @@ import (
"github.com/sirupsen/logrus"
)
const (
// DefaultResolvConf points to the default file used for dns configuration on a linux machine
DefaultResolvConf = "/etc/resolv.conf"
)
var (
// Note: the default IPv4 & IPv6 resolvers are set to Google's Public DNS
defaultIPv4Dns = []string{"nameserver 8.8.8.8", "nameserver 8.8.4.4"}
@ -50,15 +55,7 @@ type File struct {
// Get returns the contents of /etc/resolv.conf and its hash
func Get() (*File, error) {
resolv, err := ioutil.ReadFile("/etc/resolv.conf")
if err != nil {
return nil, err
}
hash, err := ioutils.HashData(bytes.NewReader(resolv))
if err != nil {
return nil, err
}
return &File{Content: resolv, Hash: hash}, nil
return GetSpecific(DefaultResolvConf)
}
// GetSpecific returns the contents of the user specified resolv.conf file and its hash

View File

@ -35,7 +35,7 @@ type Resolver interface {
}
// DNSBackend represents a backend DNS resolver used for DNS name
// resolution. All the queries to the resolver are forwared to the
// resolution. All the queries to the resolver are forwarded to the
// backend resolver.
type DNSBackend interface {
// ResolveName resolves a service name to an IPv4 or IPv6 address by searching

View File

@ -84,6 +84,7 @@ type sandbox struct {
ingress bool
ndotsSet bool
oslTypes []osl.SandboxType // slice of properties of this sandbox
loadBalancerNID string // NID that this SB is a load balancer for
sync.Mutex
// This mutex is used to serialize service related operation for an endpoint
// The lock is here because the endpoint is saved into the store so is not unique
@ -467,7 +468,7 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) {
logrus.Debugf("Service name To resolve: %v", name)
// There are DNS implementaions that allow SRV queries for names not in
// There are DNS implementations that allow SRV queries for names not in
// the format defined by RFC 2782. Hence specific validations checks are
// not done
parts := strings.Split(name, ".")
@ -1098,8 +1099,8 @@ func OptionDNSOptions(options string) SandboxOption {
}
}
// OptionUseDefaultSandbox function returns an option setter for using default sandbox to
// be passed to container Create method.
// OptionUseDefaultSandbox function returns an option setter for using default sandbox
// (host namespace) to be passed to container Create method.
func OptionUseDefaultSandbox() SandboxOption {
return func(sb *sandbox) {
sb.config.useDefaultSandBox = true
@ -1169,8 +1170,9 @@ func OptionIngress() SandboxOption {
// OptionLoadBalancer function returns an option setter for marking a
// sandbox as a load balancer sandbox.
func OptionLoadBalancer() SandboxOption {
func OptionLoadBalancer(nid string) SandboxOption {
return func(sb *sandbox) {
sb.loadBalancerNID = nid
sb.oslTypes = append(sb.oslTypes, osl.SandboxTypeLoadBalancer)
}
}

View File

@ -81,7 +81,9 @@ func (sb *sandbox) buildHostsFile() error {
}
// This is for the host mode networking
if sb.config.originHostsPath != "" {
if sb.config.useDefaultSandBox && len(sb.config.extraHosts) == 0 {
// We are working under the assumption that the origin file option had been properly expressed by the upper layer
// if not here we are going to error out
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)
}
@ -190,8 +192,13 @@ func (sb *sandbox) setupDNS() error {
return err
}
// This is for the host mode networking
if sb.config.originResolvConfPath != "" {
// When the user specify a conainter in the host namespace and do no have any dns option specified
// we just copy the host resolv.conf from the host itself
if sb.config.useDefaultSandBox &&
len(sb.config.dnsList) == 0 && len(sb.config.dnsSearchList) == 0 && len(sb.config.dnsOptionsList) == 0 {
// We are working under the assumption that the origin file option had been properly expressed by the upper layer
// if not here we are going to error out
if err := copyFile(sb.config.originResolvConfPath, sb.config.resolvConfPath); err != nil {
if !os.IsNotExist(err) {
return fmt.Errorf("could not copy source resolv.conf file %s to %s: %v", sb.config.originResolvConfPath, sb.config.resolvConfPath, err)
@ -204,7 +211,12 @@ func (sb *sandbox) setupDNS() error {
return nil
}
currRC, err := resolvconf.Get()
originResolvConfPath := sb.config.originResolvConfPath
if originResolvConfPath == "" {
// if not specified fallback to default /etc/resolv.conf
originResolvConfPath = resolvconf.DefaultResolvConf
}
currRC, err := resolvconf.GetSpecific(originResolvConfPath)
if err != nil {
if !os.IsNotExist(err) {
return err
@ -241,7 +253,7 @@ func (sb *sandbox) setupDNS() error {
sb.setExternalResolvers(newRC.Content, types.IPv4, false)
} else {
// If the host resolv.conf file has 127.0.0.x container should
// use the host restolver for queries. This is supported by the
// use the host resolver for queries. This is supported by the
// docker embedded DNS server. Hence save the external resolvers
// before filtering it out.
sb.setExternalResolvers(currRC.Content, types.IPv4, true)
@ -271,7 +283,7 @@ func (sb *sandbox) updateDNS(ipv6Enabled bool) error {
)
// This is for the host mode networking
if sb.config.originResolvConfPath != "" {
if sb.config.useDefaultSandBox {
return nil
}

View File

@ -5,7 +5,7 @@ import (
"net"
"sync"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/internal/setmatrix"
)
var (
@ -54,7 +54,7 @@ type service struct {
// associated with it. At stable state the endpoint ID expected is 1
// but during transition and service change it is possible to have
// temporary more than 1
ipToEndpoint common.SetMatrix
ipToEndpoint setmatrix.SetMatrix
deleted bool

View File

@ -5,7 +5,7 @@ package libnetwork
import (
"net"
"github.com/docker/libnetwork/common"
"github.com/docker/libnetwork/internal/setmatrix"
"github.com/sirupsen/logrus"
)
@ -139,7 +139,7 @@ func newService(name string, id string, ingressPorts []*PortConfig, serviceAlias
ingressPorts: ingressPorts,
loadBalancers: make(map[string]*loadBalancer),
aliases: serviceAliases,
ipToEndpoint: common.NewSetMatrix(),
ipToEndpoint: setmatrix.NewSetMatrix(),
}
}

View File

@ -27,7 +27,7 @@ import (
func init() {
reexec.Register("fwmarker", fwMarker)
reexec.Register("redirecter", redirecter)
reexec.Register("redirector", redirector)
}
// Populate all loadbalancers on the network that the passed endpoint
@ -431,7 +431,7 @@ func programIngress(gwIP net.IP, ingressPorts []*PortConfig, isDelete bool) erro
// DOCKER-USER so the user is able to filter packet first.
// The second rule should be jump to INGRESS-CHAIN.
// This chain has the rules to allow access to the published ports for swarm tasks
// from local bridge networks and docker_gwbridge (ie:taks on other swarm netwroks)
// from local bridge networks and docker_gwbridge (ie:taks on other swarm networks)
func arrangeIngressFilterRule() {
if iptables.ExistChain(ingressChain, iptables.Filter) {
if iptables.Exists(iptables.Filter, "FORWARD", "-j", ingressChain) {
@ -668,7 +668,7 @@ func addRedirectRules(path string, eIP *net.IPNet, ingressPorts []*PortConfig) e
cmd := &exec.Cmd{
Path: reexec.Self(),
Args: append([]string{"redirecter"}, path, eIP.String(), ingressPortsFile),
Args: append([]string{"redirector"}, path, eIP.String(), ingressPortsFile),
Stdout: os.Stdout,
Stderr: os.Stderr,
}
@ -680,8 +680,8 @@ func addRedirectRules(path string, eIP *net.IPNet, ingressPorts []*PortConfig) e
return nil
}
// Redirecter reexec function.
func redirecter() {
// Redirector reexec function.
func redirector() {
runtime.LockOSThread()
defer runtime.UnlockOSThread()