- Fixes docker/docker#19404
- Fixes ungraceful daemon restart issue in systemd with remote
network plugin (https://github.com/docker/libnetwork/issues/813)
Signed-off-by: Madhu Venugopal <madhu@docker.com>
| ... | ... |
@@ -27,7 +27,7 @@ clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de |
| 27 | 27 |
clone git github.com/imdario/mergo 0.2.1 |
| 28 | 28 |
|
| 29 | 29 |
#get libnetwork packages |
| 30 |
-clone git github.com/docker/libnetwork v0.5.6 |
|
| 30 |
+clone git github.com/docker/libnetwork v0.6.0-rc1 |
|
| 31 | 31 |
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| 32 | 32 |
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b |
| 33 | 33 |
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 |
| ... | ... |
@@ -1,5 +1,10 @@ |
| 1 | 1 |
# Changelog |
| 2 | 2 |
|
| 3 |
+## 0.6.0-rc1 (2016-01-14) |
|
| 4 |
+- Fixes docker/docker#19404 |
|
| 5 |
+- Fixes the ungraceful daemon restart issue in systemd with remote network plugin |
|
| 6 |
+ (https://github.com/docker/libnetwork/issues/813) |
|
| 7 |
+ |
|
| 3 | 8 |
## 0.5.6 (2016-01-14) |
| 4 | 9 |
- Setup embedded DNS server correctly on container restart. Fixes docker/docker#19354 |
| 5 | 10 |
|
| ... | ... |
@@ -387,7 +387,7 @@ func (c *controller) NewNetwork(networkType, name string, options ...NetworkOpti |
| 387 | 387 |
|
| 388 | 388 |
// Make sure we have a driver available for this network type |
| 389 | 389 |
// before we allocate anything. |
| 390 |
- if _, err := network.driver(); err != nil {
|
|
| 390 |
+ if _, err := network.driver(true); err != nil {
|
|
| 391 | 391 |
return nil, err |
| 392 | 392 |
} |
| 393 | 393 |
|
| ... | ... |
@@ -432,7 +432,7 @@ func (c *controller) NewNetwork(networkType, name string, options ...NetworkOpti |
| 432 | 432 |
} |
| 433 | 433 |
|
| 434 | 434 |
func (c *controller) addNetwork(n *network) error {
|
| 435 |
- d, err := n.driver() |
|
| 435 |
+ d, err := n.driver(true) |
|
| 436 | 436 |
if err != nil {
|
| 437 | 437 |
return err |
| 438 | 438 |
} |
| ... | ... |
@@ -84,7 +84,7 @@ func (sb *sandbox) clearDefaultGW() error {
|
| 84 | 84 |
return nil |
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 |
- if err := ep.sbLeave(sb); err != nil {
|
|
| 87 |
+ if err := ep.sbLeave(sb, false); err != nil {
|
|
| 88 | 88 |
return fmt.Errorf("container %s: endpoint leaving GW Network failed: %v", sb.containerID, err)
|
| 89 | 89 |
} |
| 90 | 90 |
if err := ep.Delete(false); err != nil {
|
| ... | ... |
@@ -406,7 +406,7 @@ func (ep *endpoint) sbJoin(sbox Sandbox, options ...EndpointOption) error {
|
| 406 | 406 |
|
| 407 | 407 |
ep.processOptions(options...) |
| 408 | 408 |
|
| 409 |
- driver, err := network.driver() |
|
| 409 |
+ driver, err := network.driver(true) |
|
| 410 | 410 |
if err != nil {
|
| 411 | 411 |
return fmt.Errorf("failed to join endpoint: %v", err)
|
| 412 | 412 |
} |
| ... | ... |
@@ -533,10 +533,10 @@ func (ep *endpoint) Leave(sbox Sandbox, options ...EndpointOption) error {
|
| 533 | 533 |
sb.joinLeaveStart() |
| 534 | 534 |
defer sb.joinLeaveEnd() |
| 535 | 535 |
|
| 536 |
- return ep.sbLeave(sbox, options...) |
|
| 536 |
+ return ep.sbLeave(sbox, false, options...) |
|
| 537 | 537 |
} |
| 538 | 538 |
|
| 539 |
-func (ep *endpoint) sbLeave(sbox Sandbox, options ...EndpointOption) error {
|
|
| 539 |
+func (ep *endpoint) sbLeave(sbox Sandbox, force bool, options ...EndpointOption) error {
|
|
| 540 | 540 |
sb, ok := sbox.(*sandbox) |
| 541 | 541 |
if !ok {
|
| 542 | 542 |
return types.BadRequestErrorf("not a valid Sandbox interface")
|
| ... | ... |
@@ -565,7 +565,7 @@ func (ep *endpoint) sbLeave(sbox Sandbox, options ...EndpointOption) error {
|
| 565 | 565 |
|
| 566 | 566 |
ep.processOptions(options...) |
| 567 | 567 |
|
| 568 |
- d, err := n.driver() |
|
| 568 |
+ d, err := n.driver(!force) |
|
| 569 | 569 |
if err != nil {
|
| 570 | 570 |
return fmt.Errorf("failed to leave endpoint: %v", err)
|
| 571 | 571 |
} |
| ... | ... |
@@ -575,9 +575,11 @@ func (ep *endpoint) sbLeave(sbox Sandbox, options ...EndpointOption) error {
|
| 575 | 575 |
ep.network = n |
| 576 | 576 |
ep.Unlock() |
| 577 | 577 |
|
| 578 |
- if err := d.Leave(n.id, ep.id); err != nil {
|
|
| 579 |
- if _, ok := err.(types.MaskableError); !ok {
|
|
| 580 |
- log.Warnf("driver error disconnecting container %s : %v", ep.name, err)
|
|
| 578 |
+ if d != nil {
|
|
| 579 |
+ if err := d.Leave(n.id, ep.id); err != nil {
|
|
| 580 |
+ if _, ok := err.(types.MaskableError); !ok {
|
|
| 581 |
+ log.Warnf("driver error disconnecting container %s : %v", ep.name, err)
|
|
| 582 |
+ } |
|
| 581 | 583 |
} |
| 582 | 584 |
} |
| 583 | 585 |
|
| ... | ... |
@@ -649,7 +651,7 @@ func (ep *endpoint) Delete(force bool) error {
|
| 649 | 649 |
} |
| 650 | 650 |
|
| 651 | 651 |
if sb != nil {
|
| 652 |
- if e := ep.sbLeave(sb); e != nil {
|
|
| 652 |
+ if e := ep.sbLeave(sb, force); e != nil {
|
|
| 653 | 653 |
log.Warnf("failed to leave sandbox for endpoint %s : %v", name, e)
|
| 654 | 654 |
} |
| 655 | 655 |
} |
| ... | ... |
@@ -681,7 +683,7 @@ func (ep *endpoint) Delete(force bool) error {
|
| 681 | 681 |
// unwatch for service records |
| 682 | 682 |
n.getController().unWatchSvcRecord(ep) |
| 683 | 683 |
|
| 684 |
- if err = ep.deleteEndpoint(); err != nil && !force {
|
|
| 684 |
+ if err = ep.deleteEndpoint(force); err != nil && !force {
|
|
| 685 | 685 |
return err |
| 686 | 686 |
} |
| 687 | 687 |
|
| ... | ... |
@@ -690,18 +692,22 @@ func (ep *endpoint) Delete(force bool) error {
|
| 690 | 690 |
return nil |
| 691 | 691 |
} |
| 692 | 692 |
|
| 693 |
-func (ep *endpoint) deleteEndpoint() error {
|
|
| 693 |
+func (ep *endpoint) deleteEndpoint(force bool) error {
|
|
| 694 | 694 |
ep.Lock() |
| 695 | 695 |
n := ep.network |
| 696 | 696 |
name := ep.name |
| 697 | 697 |
epid := ep.id |
| 698 | 698 |
ep.Unlock() |
| 699 | 699 |
|
| 700 |
- driver, err := n.driver() |
|
| 700 |
+ driver, err := n.driver(!force) |
|
| 701 | 701 |
if err != nil {
|
| 702 | 702 |
return fmt.Errorf("failed to delete endpoint: %v", err)
|
| 703 | 703 |
} |
| 704 | 704 |
|
| 705 |
+ if driver == nil {
|
|
| 706 |
+ return nil |
|
| 707 |
+ } |
|
| 708 |
+ |
|
| 705 | 709 |
if err := driver.DeleteEndpoint(n.id, epid); err != nil {
|
| 706 | 710 |
if _, ok := err.(types.ForbiddenError); ok {
|
| 707 | 711 |
return err |
| ... | ... |
@@ -913,7 +919,7 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
|
| 913 | 913 |
} |
| 914 | 914 |
} |
| 915 | 915 |
if progAdd != nil {
|
| 916 |
- return types.BadRequestErrorf("Invalid preferred address %s: It does not belong to any of this network's subnets")
|
|
| 916 |
+ return types.BadRequestErrorf("Invalid preferred address %s: It does not belong to any of this network's subnets", prefAdd)
|
|
| 917 | 917 |
} |
| 918 | 918 |
return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
|
| 919 | 919 |
} |
| ... | ... |
@@ -956,7 +962,7 @@ func (c *controller) cleanupLocalEndpoints() {
|
| 956 | 956 |
} |
| 957 | 957 |
|
| 958 | 958 |
for _, ep := range epl {
|
| 959 |
- if err := ep.Delete(false); err != nil {
|
|
| 959 |
+ if err := ep.Delete(true); err != nil {
|
|
| 960 | 960 |
log.Warnf("Could not delete local endpoint %s during endpoint cleanup: %v", ep.name, err)
|
| 961 | 961 |
} |
| 962 | 962 |
} |
| ... | ... |
@@ -188,7 +188,7 @@ func (ep *endpoint) DriverInfo() (map[string]interface{}, error) {
|
| 188 | 188 |
return nil, fmt.Errorf("could not find network in store for driver info: %v", err)
|
| 189 | 189 |
} |
| 190 | 190 |
|
| 191 |
- driver, err := n.driver() |
|
| 191 |
+ driver, err := n.driver(true) |
|
| 192 | 192 |
if err != nil {
|
| 193 | 193 |
return nil, fmt.Errorf("failed to get driver info: %v", err)
|
| 194 | 194 |
} |
| ... | ... |
@@ -149,6 +149,7 @@ type network struct {
|
| 149 | 149 |
name string |
| 150 | 150 |
networkType string |
| 151 | 151 |
id string |
| 152 |
+ scope string |
|
| 152 | 153 |
ipamType string |
| 153 | 154 |
ipamOptions map[string]string |
| 154 | 155 |
addrSpace string |
| ... | ... |
@@ -246,6 +247,7 @@ func (n *network) New() datastore.KVObject {
|
| 246 | 246 |
return &network{
|
| 247 | 247 |
ctrlr: n.ctrlr, |
| 248 | 248 |
drvOnce: &sync.Once{},
|
| 249 |
+ scope: n.scope, |
|
| 249 | 250 |
} |
| 250 | 251 |
} |
| 251 | 252 |
|
| ... | ... |
@@ -295,6 +297,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
|
| 295 | 295 |
dstN.name = n.name |
| 296 | 296 |
dstN.id = n.id |
| 297 | 297 |
dstN.networkType = n.networkType |
| 298 |
+ dstN.scope = n.scope |
|
| 298 | 299 |
dstN.ipamType = n.ipamType |
| 299 | 300 |
dstN.enableIPv6 = n.enableIPv6 |
| 300 | 301 |
dstN.persist = n.persist |
| ... | ... |
@@ -337,7 +340,7 @@ func (n *network) CopyTo(o datastore.KVObject) error {
|
| 337 | 337 |
} |
| 338 | 338 |
|
| 339 | 339 |
func (n *network) DataScope() string {
|
| 340 |
- return n.driverScope() |
|
| 340 |
+ return n.Scope() |
|
| 341 | 341 |
} |
| 342 | 342 |
|
| 343 | 343 |
func (n *network) getEpCnt() *endpointCnt {
|
| ... | ... |
@@ -353,6 +356,7 @@ func (n *network) MarshalJSON() ([]byte, error) {
|
| 353 | 353 |
netMap["name"] = n.name |
| 354 | 354 |
netMap["id"] = n.id |
| 355 | 355 |
netMap["networkType"] = n.networkType |
| 356 |
+ netMap["scope"] = n.scope |
|
| 356 | 357 |
netMap["ipamType"] = n.ipamType |
| 357 | 358 |
netMap["addrSpace"] = n.addrSpace |
| 358 | 359 |
netMap["enableIPv6"] = n.enableIPv6 |
| ... | ... |
@@ -456,6 +460,9 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
|
| 456 | 456 |
if v, ok := netMap["internal"]; ok {
|
| 457 | 457 |
n.internal = v.(bool) |
| 458 | 458 |
} |
| 459 |
+ if s, ok := netMap["scope"]; ok {
|
|
| 460 |
+ n.scope = s.(string) |
|
| 461 |
+ } |
|
| 459 | 462 |
return nil |
| 460 | 463 |
} |
| 461 | 464 |
|
| ... | ... |
@@ -566,7 +573,7 @@ func (n *network) driverScope() string {
|
| 566 | 566 |
return dd.capability.DataScope |
| 567 | 567 |
} |
| 568 | 568 |
|
| 569 |
-func (n *network) driver() (driverapi.Driver, error) {
|
|
| 569 |
+func (n *network) driver(load bool) (driverapi.Driver, error) {
|
|
| 570 | 570 |
c := n.getController() |
| 571 | 571 |
|
| 572 | 572 |
c.Lock() |
| ... | ... |
@@ -574,14 +581,20 @@ func (n *network) driver() (driverapi.Driver, error) {
|
| 574 | 574 |
dd, ok := c.drivers[n.networkType] |
| 575 | 575 |
c.Unlock() |
| 576 | 576 |
|
| 577 |
- if !ok {
|
|
| 577 |
+ if !ok && load {
|
|
| 578 | 578 |
var err error |
| 579 | 579 |
dd, err = c.loadDriver(n.networkType) |
| 580 | 580 |
if err != nil {
|
| 581 | 581 |
return nil, err |
| 582 | 582 |
} |
| 583 |
+ } else if !ok {
|
|
| 584 |
+ // dont fail if driver loading is not required |
|
| 585 |
+ return nil, nil |
|
| 583 | 586 |
} |
| 584 | 587 |
|
| 588 |
+ n.Lock() |
|
| 589 |
+ n.scope = dd.capability.DataScope |
|
| 590 |
+ n.Unlock() |
|
| 585 | 591 |
return dd.driver, nil |
| 586 | 592 |
} |
| 587 | 593 |
|
| ... | ... |
@@ -631,7 +644,7 @@ func (n *network) Delete() error {
|
| 631 | 631 |
} |
| 632 | 632 |
|
| 633 | 633 |
func (n *network) deleteNetwork() error {
|
| 634 |
- d, err := n.driver() |
|
| 634 |
+ d, err := n.driver(true) |
|
| 635 | 635 |
if err != nil {
|
| 636 | 636 |
return fmt.Errorf("failed deleting network: %v", err)
|
| 637 | 637 |
} |
| ... | ... |
@@ -651,7 +664,7 @@ func (n *network) deleteNetwork() error {
|
| 651 | 651 |
} |
| 652 | 652 |
|
| 653 | 653 |
func (n *network) addEndpoint(ep *endpoint) error {
|
| 654 |
- d, err := n.driver() |
|
| 654 |
+ d, err := n.driver(true) |
|
| 655 | 655 |
if err != nil {
|
| 656 | 656 |
return fmt.Errorf("failed to add endpoint: %v", err)
|
| 657 | 657 |
} |
| ... | ... |
@@ -725,7 +738,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi |
| 725 | 725 |
} |
| 726 | 726 |
defer func() {
|
| 727 | 727 |
if err != nil {
|
| 728 |
- if e := ep.deleteEndpoint(); e != nil {
|
|
| 728 |
+ if e := ep.deleteEndpoint(false); e != nil {
|
|
| 729 | 729 |
log.Warnf("cleaning up endpoint failed %s : %v", name, e)
|
| 730 | 730 |
} |
| 731 | 731 |
} |
| ... | ... |
@@ -1169,7 +1182,9 @@ func (n *network) DriverOptions() map[string]string {
|
| 1169 | 1169 |
} |
| 1170 | 1170 |
|
| 1171 | 1171 |
func (n *network) Scope() string {
|
| 1172 |
- return n.driverScope() |
|
| 1172 |
+ n.Lock() |
|
| 1173 |
+ defer n.Unlock() |
|
| 1174 |
+ return n.scope |
|
| 1173 | 1175 |
} |
| 1174 | 1176 |
|
| 1175 | 1177 |
func (n *network) IpamConfig() (string, map[string]string, []*IpamConf, []*IpamConf) {
|
| ... | ... |
@@ -160,6 +160,10 @@ func (sb *sandbox) Statistics() (map[string]*types.InterfaceStatistics, error) {
|
| 160 | 160 |
} |
| 161 | 161 |
|
| 162 | 162 |
func (sb *sandbox) Delete() error {
|
| 163 |
+ return sb.delete(false) |
|
| 164 |
+} |
|
| 165 |
+ |
|
| 166 |
+func (sb *sandbox) delete(force bool) error {
|
|
| 163 | 167 |
sb.Lock() |
| 164 | 168 |
if sb.inDelete {
|
| 165 | 169 |
sb.Unlock() |
| ... | ... |
@@ -194,11 +198,13 @@ func (sb *sandbox) Delete() error {
|
| 194 | 194 |
continue |
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 |
- if err := ep.Leave(sb); err != nil {
|
|
| 198 |
- log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
|
|
| 197 |
+ if !force {
|
|
| 198 |
+ if err := ep.Leave(sb); err != nil {
|
|
| 199 |
+ log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
|
|
| 200 |
+ } |
|
| 199 | 201 |
} |
| 200 | 202 |
|
| 201 |
- if err := ep.Delete(false); err != nil {
|
|
| 203 |
+ if err := ep.Delete(force); err != nil {
|
|
| 202 | 204 |
log.Warnf("Failed deleting endpoint %s: %v\n", ep.ID(), err)
|
| 203 | 205 |
} |
| 204 | 206 |
} |
| ... | ... |
@@ -226,7 +226,7 @@ func (c *controller) sandboxCleanup() {
|
| 226 | 226 |
heap.Push(&sb.endpoints, ep) |
| 227 | 227 |
} |
| 228 | 228 |
|
| 229 |
- if err := sb.Delete(); err != nil {
|
|
| 229 |
+ if err := sb.delete(true); err != nil {
|
|
| 230 | 230 |
logrus.Errorf("failed to delete sandbox %s while trying to cleanup: %v", sb.id, err)
|
| 231 | 231 |
} |
| 232 | 232 |
} |
| ... | ... |
@@ -75,6 +75,7 @@ func (c *controller) getNetworkFromStore(nid string) (*network, error) {
|
| 75 | 75 |
} |
| 76 | 76 |
|
| 77 | 77 |
n.epCnt = ec |
| 78 |
+ n.scope = store.Scope() |
|
| 78 | 79 |
return n, nil |
| 79 | 80 |
} |
| 80 | 81 |
|
| ... | ... |
@@ -107,6 +108,7 @@ func (c *controller) getNetworksForScope(scope string) ([]*network, error) {
|
| 107 | 107 |
} |
| 108 | 108 |
|
| 109 | 109 |
n.epCnt = ec |
| 110 |
+ n.scope = scope |
|
| 110 | 111 |
nl = append(nl, n) |
| 111 | 112 |
} |
| 112 | 113 |
|
| ... | ... |
@@ -140,6 +142,7 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
|
| 140 | 140 |
} |
| 141 | 141 |
|
| 142 | 142 |
n.epCnt = ec |
| 143 |
+ n.scope = store.Scope() |
|
| 143 | 144 |
nl = append(nl, n) |
| 144 | 145 |
} |
| 145 | 146 |
} |
| ... | ... |
@@ -148,17 +151,21 @@ func (c *controller) getNetworksFromStore() ([]*network, error) {
|
| 148 | 148 |
} |
| 149 | 149 |
|
| 150 | 150 |
func (n *network) getEndpointFromStore(eid string) (*endpoint, error) {
|
| 151 |
- store := n.ctrlr.getStore(n.Scope()) |
|
| 152 |
- if store == nil {
|
|
| 153 |
- return nil, fmt.Errorf("could not find endpoint %s: datastore not found for scope %s", eid, n.Scope())
|
|
| 154 |
- } |
|
| 155 |
- |
|
| 156 |
- ep := &endpoint{id: eid, network: n}
|
|
| 157 |
- err := store.GetObject(datastore.Key(ep.Key()...), ep) |
|
| 158 |
- if err != nil {
|
|
| 159 |
- return nil, fmt.Errorf("could not find endpoint %s: %v", eid, err)
|
|
| 151 |
+ var errors []string |
|
| 152 |
+ for _, store := range n.ctrlr.getStores() {
|
|
| 153 |
+ ep := &endpoint{id: eid, network: n}
|
|
| 154 |
+ err := store.GetObject(datastore.Key(ep.Key()...), ep) |
|
| 155 |
+ // Continue searching in the next store if the key is not found in this store |
|
| 156 |
+ if err != nil {
|
|
| 157 |
+ if err != datastore.ErrKeyNotFound {
|
|
| 158 |
+ errors = append(errors, fmt.Sprintf("{%s:%v}, ", store.Scope(), err))
|
|
| 159 |
+ log.Debugf("could not find endpoint %s in %s: %v", eid, store.Scope(), err)
|
|
| 160 |
+ } |
|
| 161 |
+ continue |
|
| 162 |
+ } |
|
| 163 |
+ return ep, nil |
|
| 160 | 164 |
} |
| 161 |
- return ep, nil |
|
| 165 |
+ return nil, fmt.Errorf("could not find endpoint %s: %v", eid, errors)
|
|
| 162 | 166 |
} |
| 163 | 167 |
|
| 164 | 168 |
func (n *network) getEndpointsFromStore() ([]*endpoint, error) {
|