Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -26,7 +26,7 @@ clone git github.com/docker/engine-api v0.2.2 |
| 26 | 26 |
clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de |
| 27 | 27 |
|
| 28 | 28 |
#get libnetwork packages |
| 29 |
-clone git github.com/docker/libnetwork v0.5.4 |
|
| 29 |
+clone git github.com/docker/libnetwork v0.5.5 |
|
| 30 | 30 |
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| 31 | 31 |
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b |
| 32 | 32 |
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 |
| ... | ... |
@@ -1,5 +1,10 @@ |
| 1 | 1 |
# Changelog |
| 2 | 2 |
|
| 3 |
+## 0.5.5 (2016-01-14) |
|
| 4 |
+- Allow network-scoped alias to be resolved for anonymous endpoint |
|
| 5 |
+- Self repair corrupted IP database that could happen in 1.9.0 & 1.9.1 |
|
| 6 |
+- Skip IPTables cleanup if --iptables=false is set. Fixes docker/docker#19063 |
|
| 7 |
+ |
|
| 3 | 8 |
## 0.5.4 (2016-01-12) |
| 4 | 9 |
- Removed the isNodeAlive protection when user forces an endpoint delete |
| 5 | 10 |
|
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"fmt" |
| 10 | 10 |
"sync" |
| 11 | 11 |
|
| 12 |
+ log "github.com/Sirupsen/logrus" |
|
| 12 | 13 |
"github.com/docker/libnetwork/datastore" |
| 13 | 14 |
"github.com/docker/libnetwork/types" |
| 14 | 15 |
) |
| ... | ... |
@@ -243,6 +244,58 @@ func (h *Handle) IsSet(ordinal uint64) bool {
|
| 243 | 243 |
return err != nil |
| 244 | 244 |
} |
| 245 | 245 |
|
| 246 |
+func (h *Handle) runConsistencyCheck() bool {
|
|
| 247 |
+ corrupted := false |
|
| 248 |
+ for p, c := h.head, h.head.next; c != nil; c = c.next {
|
|
| 249 |
+ if c.count == 0 {
|
|
| 250 |
+ corrupted = true |
|
| 251 |
+ p.next = c.next |
|
| 252 |
+ continue // keep same p |
|
| 253 |
+ } |
|
| 254 |
+ p = c |
|
| 255 |
+ } |
|
| 256 |
+ return corrupted |
|
| 257 |
+} |
|
| 258 |
+ |
|
| 259 |
+// CheckConsistency checks if the bit sequence is in an inconsistent state and attempts to fix it. |
|
| 260 |
+// It looks for a corruption signature that may happen in docker 1.9.0 and 1.9.1. |
|
| 261 |
+func (h *Handle) CheckConsistency() error {
|
|
| 262 |
+ for {
|
|
| 263 |
+ h.Lock() |
|
| 264 |
+ store := h.store |
|
| 265 |
+ h.Unlock() |
|
| 266 |
+ |
|
| 267 |
+ if store != nil {
|
|
| 268 |
+ if err := store.GetObject(datastore.Key(h.Key()...), h); err != nil && err != datastore.ErrKeyNotFound {
|
|
| 269 |
+ return err |
|
| 270 |
+ } |
|
| 271 |
+ } |
|
| 272 |
+ |
|
| 273 |
+ h.Lock() |
|
| 274 |
+ nh := h.getCopy() |
|
| 275 |
+ h.Unlock() |
|
| 276 |
+ |
|
| 277 |
+ if !nh.runConsistencyCheck() {
|
|
| 278 |
+ return nil |
|
| 279 |
+ } |
|
| 280 |
+ |
|
| 281 |
+ if err := nh.writeToStore(); err != nil {
|
|
| 282 |
+ if _, ok := err.(types.RetryError); !ok {
|
|
| 283 |
+ return fmt.Errorf("internal failure while fixing inconsistent bitsequence: %v", err)
|
|
| 284 |
+ } |
|
| 285 |
+ continue |
|
| 286 |
+ } |
|
| 287 |
+ |
|
| 288 |
+ log.Infof("Fixed inconsistent bit sequence in datastore:\n%s\n%s", h, nh)
|
|
| 289 |
+ |
|
| 290 |
+ h.Lock() |
|
| 291 |
+ h.head = nh.head |
|
| 292 |
+ h.Unlock() |
|
| 293 |
+ |
|
| 294 |
+ return nil |
|
| 295 |
+ } |
|
| 296 |
+} |
|
| 297 |
+ |
|
| 246 | 298 |
// set/reset the bit |
| 247 | 299 |
func (h *Handle) set(ordinal, start, end uint64, any bool, release bool) (uint64, error) {
|
| 248 | 300 |
var ( |
| ... | ... |
@@ -135,7 +135,7 @@ func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
|
| 135 | 135 |
if err := iptables.FirewalldInit(); err != nil {
|
| 136 | 136 |
logrus.Debugf("Fail to initialize firewalld: %v, using raw iptables instead", err)
|
| 137 | 137 |
} |
| 138 |
- removeIPChains() |
|
| 138 |
+ |
|
| 139 | 139 |
d := newDriver() |
| 140 | 140 |
if err := d.configure(config); err != nil {
|
| 141 | 141 |
return err |
| ... | ... |
@@ -378,6 +378,7 @@ func (d *driver) configure(option map[string]interface{}) error {
|
| 378 | 378 |
} |
| 379 | 379 |
|
| 380 | 380 |
if config.EnableIPTables {
|
| 381 |
+ removeIPChains() |
|
| 381 | 382 |
natChain, filterChain, isolationChain, err = setupIPChains(config) |
| 382 | 383 |
if err != nil {
|
| 383 | 384 |
return err |
| ... | ... |
@@ -70,6 +70,9 @@ func NewAllocator(lcDs, glDs datastore.DataStore) (*Allocator, error) {
|
| 70 | 70 |
} |
| 71 | 71 |
} |
| 72 | 72 |
|
| 73 |
+ a.checkConsistency(localAddressSpace) |
|
| 74 |
+ a.checkConsistency(globalAddressSpace) |
|
| 75 |
+ |
|
| 73 | 76 |
return a, nil |
| 74 | 77 |
} |
| 75 | 78 |
|
| ... | ... |
@@ -115,6 +118,25 @@ func (a *Allocator) updateBitMasks(aSpace *addrSpace) error {
|
| 115 | 115 |
return nil |
| 116 | 116 |
} |
| 117 | 117 |
|
| 118 |
+// Checks for and fixes damaged bitmask. Meant to be called in constructor only. |
|
| 119 |
+func (a *Allocator) checkConsistency(as string) {
|
|
| 120 |
+ // Retrieve this address space's configuration and bitmasks from the datastore |
|
| 121 |
+ a.refresh(as) |
|
| 122 |
+ aSpace, ok := a.addrSpaces[as] |
|
| 123 |
+ if !ok {
|
|
| 124 |
+ return |
|
| 125 |
+ } |
|
| 126 |
+ a.updateBitMasks(aSpace) |
|
| 127 |
+ for sk, pd := range aSpace.subnets {
|
|
| 128 |
+ if pd.Range != nil {
|
|
| 129 |
+ continue |
|
| 130 |
+ } |
|
| 131 |
+ if err := a.addresses[sk].CheckConsistency(); err != nil {
|
|
| 132 |
+ log.Warnf("Error while running consistency check for %s: %v", sk, err)
|
|
| 133 |
+ } |
|
| 134 |
+ } |
|
| 135 |
+} |
|
| 136 |
+ |
|
| 118 | 137 |
// GetDefaultAddressSpaces returns the local and global default address spaces |
| 119 | 138 |
func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
|
| 120 | 139 |
return localAddressSpace, globalAddressSpace, nil |
| ... | ... |
@@ -822,20 +822,20 @@ func (n *network) EndpointByID(id string) (Endpoint, error) {
|
| 822 | 822 |
} |
| 823 | 823 |
|
| 824 | 824 |
func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool) {
|
| 825 |
- if ep.isAnonymous() {
|
|
| 826 |
- return |
|
| 827 |
- } |
|
| 828 |
- |
|
| 829 | 825 |
epName := ep.Name() |
| 830 | 826 |
if iface := ep.Iface(); iface.Address() != nil {
|
| 831 | 827 |
myAliases := ep.MyAliases() |
| 832 | 828 |
if isAdd {
|
| 833 |
- n.addSvcRecords(epName, iface.Address().IP, true) |
|
| 829 |
+ if !ep.isAnonymous() {
|
|
| 830 |
+ n.addSvcRecords(epName, iface.Address().IP, true) |
|
| 831 |
+ } |
|
| 834 | 832 |
for _, alias := range myAliases {
|
| 835 | 833 |
n.addSvcRecords(alias, iface.Address().IP, false) |
| 836 | 834 |
} |
| 837 | 835 |
} else {
|
| 838 |
- n.deleteSvcRecords(epName, iface.Address().IP, true) |
|
| 836 |
+ if !ep.isAnonymous() {
|
|
| 837 |
+ n.deleteSvcRecords(epName, iface.Address().IP, true) |
|
| 838 |
+ } |
|
| 839 | 839 |
for _, alias := range myAliases {
|
| 840 | 840 |
n.deleteSvcRecords(alias, iface.Address().IP, false) |
| 841 | 841 |
} |