1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Move load balancer sandbox creation/deletion into libnetwork.

Signed-off-by: Pradip Dhara <pradipd@microsoft.com>
This commit is contained in:
Pradip Dhara 2017-11-04 13:58:54 -07:00
parent a7aa2b2bf8
commit 0d1f9c4c97
2 changed files with 162 additions and 36 deletions

View file

@ -837,10 +837,24 @@ 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
}
if len(network.loadBalancerIP) != 0 {
if err = network.createLoadBalancerSandbox(); err != nil {
return nil, err
}
}
joinCluster(network)
if !c.isDistributedControl() {
c.Lock()

View file

@ -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,83 @@ 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
}
if err := sb.EnableService(); err != nil {
return err
}
return nil
}
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)
}
}