From 7de313ac4ec2084aca6c91efc3124b9dbffc5f1a Mon Sep 17 00:00:00 2001 From: Pradip Dhara Date: Thu, 30 Nov 2017 13:02:56 -0800 Subject: [PATCH] vndr libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7 Signed-off-by: Pradip Dhara --- vendor.conf | 2 +- .../docker/libnetwork/controller.go | 23 +++ .../github.com/docker/libnetwork/network.go | 181 ++++++++++++++---- vendor/github.com/docker/libnetwork/store.go | 2 +- 4 files changed, 170 insertions(+), 38 deletions(-) diff --git a/vendor.conf b/vendor.conf index 10aa633c97..dd2d9c72ff 100644 --- a/vendor.conf +++ b/vendor.conf @@ -30,7 +30,7 @@ github.com/moby/buildkit aaff9d591ef128560018433fe61beb802e149de8 github.com/tonistiigi/fsutil dea3a0da73aee887fc02142d995be764106ac5e2 #get libnetwork packages -github.com/docker/libnetwork f7d21337cf1eb628ad54eecac0881fa23ec266df +github.com/docker/libnetwork 64ae58878fc8f95e4a167499d654e13fa36abdc7 github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9 github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec diff --git a/vendor/github.com/docker/libnetwork/controller.go b/vendor/github.com/docker/libnetwork/controller.go index 236095c8ac..24494ae834 100644 --- a/vendor/github.com/docker/libnetwork/controller.go +++ b/vendor/github.com/docker/libnetwork/controller.go @@ -837,11 +837,34 @@ addToStore: if err = c.updateToStore(network); err != nil { return nil, err } + defer func() { + if err != nil { + if e := c.deleteFromStore(network); e != nil { + logrus.Warnf("could not rollback from store, network %v on failure (%v): %v", network, err, e) + } + } + }() + if network.configOnly { return network, nil } joinCluster(network) + defer func() { + if err != nil { + network.cancelDriverWatches() + if e := network.leaveCluster(); e != nil { + logrus.Warnf("Failed to leave agent cluster on network %s on failure (%v): %v", network.name, err, e) + } + } + }() + + if len(network.loadBalancerIP) != 0 { + if err = network.createLoadBalancerSandbox(); err != nil { + return nil, err + } + } + if !c.isDistributedControl() { c.Lock() arrangeIngressFilterRule() diff --git a/vendor/github.com/docker/libnetwork/network.go b/vendor/github.com/docker/libnetwork/network.go index 1ad4706ff8..318c3956c0 100644 --- a/vendor/github.com/docker/libnetwork/network.go +++ b/vendor/github.com/docker/libnetwork/network.go @@ -199,39 +199,40 @@ func (i *IpamInfo) UnmarshalJSON(data []byte) error { } type network struct { - ctrlr *controller - name string - networkType string - id string - created time.Time - scope string // network data scope - labels map[string]string - ipamType string - ipamOptions map[string]string - addrSpace string - ipamV4Config []*IpamConf - ipamV6Config []*IpamConf - ipamV4Info []*IpamInfo - ipamV6Info []*IpamInfo - enableIPv6 bool - postIPv6 bool - epCnt *endpointCnt - generic options.Generic - dbIndex uint64 - dbExists bool - persist bool - stopWatchCh chan struct{} - drvOnce *sync.Once - resolverOnce sync.Once - resolver []Resolver - internal bool - attachable bool - inDelete bool - ingress bool - driverTables []networkDBTable - dynamic bool - configOnly bool - configFrom string + ctrlr *controller + name string + networkType string + id string + created time.Time + scope string // network data scope + labels map[string]string + ipamType string + ipamOptions map[string]string + addrSpace string + ipamV4Config []*IpamConf + ipamV6Config []*IpamConf + ipamV4Info []*IpamInfo + ipamV6Info []*IpamInfo + enableIPv6 bool + postIPv6 bool + epCnt *endpointCnt + generic options.Generic + dbIndex uint64 + dbExists bool + persist bool + stopWatchCh chan struct{} + drvOnce *sync.Once + resolverOnce sync.Once + resolver []Resolver + internal bool + attachable bool + inDelete bool + ingress bool + driverTables []networkDBTable + dynamic bool + configOnly bool + configFrom string + loadBalancerIP net.IP sync.Mutex } @@ -473,6 +474,7 @@ func (n *network) CopyTo(o datastore.KVObject) error { dstN.ingress = n.ingress dstN.configOnly = n.configOnly dstN.configFrom = n.configFrom + dstN.loadBalancerIP = n.loadBalancerIP // copy labels if dstN.labels == nil { @@ -589,6 +591,7 @@ func (n *network) MarshalJSON() ([]byte, error) { netMap["ingress"] = n.ingress netMap["configOnly"] = n.configOnly netMap["configFrom"] = n.configFrom + netMap["loadBalancerIP"] = n.loadBalancerIP return json.Marshal(netMap) } @@ -699,6 +702,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) { if v, ok := netMap["configFrom"]; ok { n.configFrom = v.(string) } + if v, ok := netMap["loadBalancerIP"]; ok { + n.loadBalancerIP = net.ParseIP(v.(string)) + } // Reconcile old networks with the recently added `--ipv6` flag if !n.enableIPv6 { n.enableIPv6 = len(n.ipamV6Info) > 0 @@ -799,6 +805,13 @@ func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ip } } +// NetworkOptionLBEndpoint function returns an option setter for the configuration of the load balancer endpoint for this network +func NetworkOptionLBEndpoint(ip net.IP) NetworkOption { + return func(n *network) { + n.loadBalancerIP = ip + } +} + // NetworkOptionDriverOpts function returns an option setter for any driver parameter described by a map func NetworkOptionDriverOpts(opts map[string]string) NetworkOption { return func(n *network) { @@ -944,6 +957,18 @@ func (n *network) delete(force bool) error { return &UnknownNetworkError{name: name, id: id} } + if len(n.loadBalancerIP) != 0 { + endpoints := n.Endpoints() + if force || len(endpoints) == 1 { + n.deleteLoadBalancerSandbox() + } + //Reload the network from the store to update the epcnt. + n, err = c.getNetworkFromStore(id) + if err != nil { + return &UnknownNetworkError{name: name, id: id} + } + } + if !force && n.getEpCnt().EndpointCnt() != 0 { if n.configOnly { return types.ForbiddenErrorf("configuration network %q is in use", n.Name()) @@ -1071,12 +1096,19 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi return nil, types.ForbiddenErrorf("endpoint with name %s already exists in network %s", name, n.Name()) } - ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} - ep.id = stringid.GenerateRandomID() - n.ctrlr.networkLocker.Lock(n.id) defer n.ctrlr.networkLocker.Unlock(n.id) + return n.createEndpoint(name, options...) + +} + +func (n *network) createEndpoint(name string, options ...EndpointOption) (Endpoint, error) { + var err error + + ep := &endpoint{name: name, generic: make(map[string]interface{}), iface: &endpointInterface{}} + ep.id = stringid.GenerateRandomID() + // Initialize ep.network with a possibly stale copy of n. We need this to get network from // store. But once we get it from store we will have the most uptodate copy possibly. ep.network = n @@ -2021,3 +2053,80 @@ func (c *controller) getConfigNetwork(name string) (*network, error) { return n.(*network), nil } + +func (n *network) createLoadBalancerSandbox() error { + sandboxName := n.name + "-sbox" + sbOptions := []SandboxOption{} + if n.ingress { + sbOptions = append(sbOptions, OptionIngress()) + } + sb, err := n.ctrlr.NewSandbox(sandboxName, sbOptions...) + if err != nil { + return err + } + defer func() { + if err != nil { + if e := n.ctrlr.SandboxDestroy(sandboxName); e != nil { + logrus.Warnf("could not delete sandbox %s on failure on failure (%v): %v", sandboxName, err, e) + } + } + }() + + endpointName := n.name + "-endpoint" + epOptions := []EndpointOption{ + CreateOptionIpam(n.loadBalancerIP, nil, nil, nil), + CreateOptionLoadBalancer(), + } + ep, err := n.createEndpoint(endpointName, epOptions...) + if err != nil { + return err + } + defer func() { + if err != nil { + if e := ep.Delete(true); e != nil { + logrus.Warnf("could not delete endpoint %s on failure on failure (%v): %v", endpointName, err, e) + } + } + }() + + if err := ep.Join(sb, nil); err != nil { + return err + } + return sb.EnableService() +} + +func (n *network) deleteLoadBalancerSandbox() { + n.Lock() + c := n.ctrlr + name := n.name + n.Unlock() + + endpointName := name + "-endpoint" + sandboxName := name + "-sbox" + + endpoint, err := n.EndpointByName(endpointName) + if err != nil { + logrus.Warnf("Failed to find load balancer endpoint %s on network %s: %v", endpointName, name, err) + } else { + + info := endpoint.Info() + if info != nil { + sb := info.Sandbox() + if sb != nil { + if err := sb.DisableService(); err != nil { + logrus.Warnf("Failed to disable service on sandbox %s: %v", sandboxName, err) + //Ignore error and attempt to delete the load balancer endpoint + } + } + } + + if err := endpoint.Delete(true); err != nil { + logrus.Warnf("Failed to delete endpoint %s (%s) in %s: %v", endpoint.Name(), endpoint.ID(), sandboxName, err) + //Ignore error and attempt to delete the sandbox. + } + } + + if err := c.SandboxDestroy(sandboxName); err != nil { + logrus.Warnf("Failed to delete %s sandbox: %v", sandboxName, err) + } +} diff --git a/vendor/github.com/docker/libnetwork/store.go b/vendor/github.com/docker/libnetwork/store.go index da7ac1dea6..95943f6f45 100644 --- a/vendor/github.com/docker/libnetwork/store.go +++ b/vendor/github.com/docker/libnetwork/store.go @@ -256,7 +256,7 @@ retry: if err := cs.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) } - logrus.Errorf("Error (%v) deleting object %v, retrying....", err, kvObject.Key()) + logrus.Warnf("Error (%v) deleting object %v, retrying....", err, kvObject.Key()) goto retry } return err