зеркало из https://github.com/microsoft/docker.git
Vendor libnetwork v0.6.0-rc3
- Fixes docker/docker#19576 - Fixed embedded DNS to listen in TCP as well - Fixed a race-condition in IPAM to choose non-overlapping subnet for concurrent requests Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Родитель
15cc67b73d
Коммит
6ac9a2f410
|
@ -27,7 +27,7 @@ clone git github.com/RackSec/srslog 6eb773f331e46fbba8eecb8e794e635e75fc04de
|
||||||
clone git github.com/imdario/mergo 0.2.1
|
clone git github.com/imdario/mergo 0.2.1
|
||||||
|
|
||||||
#get libnetwork packages
|
#get libnetwork packages
|
||||||
clone git github.com/docker/libnetwork v0.6.0-rc2
|
clone git github.com/docker/libnetwork v0.6.0-rc3
|
||||||
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
|
||||||
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
|
||||||
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.6.0-rc3 (2016-01-25)
|
||||||
|
- Fixes docker/docker#19576
|
||||||
|
- Fixed embedded DNS to listen in TCP as well
|
||||||
|
- Fixed a race-condition in IPAM to choose non-overlapping subnet for concurrent requests
|
||||||
|
|
||||||
## 0.6.0-rc2 (2016-01-21)
|
## 0.6.0-rc2 (2016-01-21)
|
||||||
- Fixes docker/docker#19376
|
- Fixes docker/docker#19376
|
||||||
- Fixes docker/docker#15819
|
- Fixes docker/docker#15819
|
||||||
|
|
|
@ -63,7 +63,7 @@ run-tests:
|
||||||
if ls $$dir/*.go &> /dev/null; then \
|
if ls $$dir/*.go &> /dev/null; then \
|
||||||
pushd . &> /dev/null ; \
|
pushd . &> /dev/null ; \
|
||||||
cd $$dir ; \
|
cd $$dir ; \
|
||||||
$(shell which godep) go test ${INSIDECONTAINER} -test.parallel 3 -test.v -covermode=count -coverprofile=./profile.tmp ; \
|
$(shell which godep) go test ${INSIDECONTAINER} -test.parallel 5 -test.v -covermode=count -coverprofile=./profile.tmp ; \
|
||||||
ret=$$? ;\
|
ret=$$? ;\
|
||||||
if [ $$ret -ne 0 ]; then exit $$ret; fi ;\
|
if [ $$ret -ne 0 ]; then exit $$ret; fi ;\
|
||||||
popd &> /dev/null; \
|
popd &> /dev/null; \
|
||||||
|
|
|
@ -465,7 +465,7 @@ func (ep *endpoint) sbJoin(sbox Sandbox, options ...EndpointOption) error {
|
||||||
if sb.needDefaultGW() {
|
if sb.needDefaultGW() {
|
||||||
return sb.setupDefaultGW(ep)
|
return sb.setupDefaultGW(ep)
|
||||||
}
|
}
|
||||||
return sb.clearDefaultGW()
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ep *endpoint) rename(name string) error {
|
func (ep *endpoint) rename(name string) error {
|
||||||
|
@ -597,15 +597,7 @@ func (ep *endpoint) sbLeave(sbox Sandbox, force bool, options ...EndpointOption)
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.deleteHostsEntries(n.getSvcRecords(ep))
|
sb.deleteHostsEntries(n.getSvcRecords(ep))
|
||||||
|
return nil
|
||||||
if !sb.inDelete && sb.needDefaultGW() {
|
|
||||||
ep := sb.getEPwithoutGateway()
|
|
||||||
if ep == nil {
|
|
||||||
return fmt.Errorf("endpoint without GW expected, but not found")
|
|
||||||
}
|
|
||||||
return sb.setupDefaultGW(ep)
|
|
||||||
}
|
|
||||||
return sb.clearDefaultGW()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *network) validateForceDelete(locator string) error {
|
func (n *network) validateForceDelete(locator string) error {
|
||||||
|
|
|
@ -145,12 +145,12 @@ func (a *Allocator) GetDefaultAddressSpaces() (string, string, error) {
|
||||||
// RequestPool returns an address pool along with its unique id.
|
// RequestPool returns an address pool along with its unique id.
|
||||||
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
func (a *Allocator) RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error) {
|
||||||
log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
log.Debugf("RequestPool(%s, %s, %s, %v, %t)", addressSpace, pool, subPool, options, v6)
|
||||||
k, nw, ipr, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
retry:
|
||||||
|
k, nw, ipr, pdf, err := a.parsePoolRequest(addressSpace, pool, subPool, v6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err)
|
return "", nil, nil, types.InternalErrorf("failed to parse pool request for address space %q pool %q subpool %q: %v", addressSpace, pool, subPool, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
|
||||||
if err := a.refresh(addressSpace); err != nil {
|
if err := a.refresh(addressSpace); err != nil {
|
||||||
return "", nil, nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -160,8 +160,12 @@ retry:
|
||||||
return "", nil, nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr)
|
insert, err := aSpace.updatePoolDBOnAdd(*k, nw, ipr, pdf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if _, ok := err.(types.MaskableError); ok {
|
||||||
|
log.Debugf("Retrying predefined pool search: %v", err)
|
||||||
|
goto retry
|
||||||
|
}
|
||||||
return "", nil, nil, err
|
return "", nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,38 +225,39 @@ func (a *Allocator) getAddrSpace(as string) (*addrSpace, error) {
|
||||||
return aSpace, nil
|
return aSpace, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, error) {
|
func (a *Allocator) parsePoolRequest(addressSpace, pool, subPool string, v6 bool) (*SubnetKey, *net.IPNet, *AddressRange, bool, error) {
|
||||||
var (
|
var (
|
||||||
nw *net.IPNet
|
nw *net.IPNet
|
||||||
ipr *AddressRange
|
ipr *AddressRange
|
||||||
err error
|
err error
|
||||||
|
pdf = false
|
||||||
)
|
)
|
||||||
|
|
||||||
if addressSpace == "" {
|
if addressSpace == "" {
|
||||||
return nil, nil, nil, ipamapi.ErrInvalidAddressSpace
|
return nil, nil, nil, false, ipamapi.ErrInvalidAddressSpace
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool == "" && subPool != "" {
|
if pool == "" && subPool != "" {
|
||||||
return nil, nil, nil, ipamapi.ErrInvalidSubPool
|
return nil, nil, nil, false, ipamapi.ErrInvalidSubPool
|
||||||
}
|
}
|
||||||
|
|
||||||
if pool != "" {
|
if pool != "" {
|
||||||
if _, nw, err = net.ParseCIDR(pool); err != nil {
|
if _, nw, err = net.ParseCIDR(pool); err != nil {
|
||||||
return nil, nil, nil, ipamapi.ErrInvalidPool
|
return nil, nil, nil, false, ipamapi.ErrInvalidPool
|
||||||
}
|
}
|
||||||
if subPool != "" {
|
if subPool != "" {
|
||||||
if ipr, err = getAddressRange(subPool, nw); err != nil {
|
if ipr, err = getAddressRange(subPool, nw); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
|
if nw, err = a.getPredefinedPool(addressSpace, v6); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, false, err
|
||||||
}
|
}
|
||||||
|
pdf = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, nil
|
return &SubnetKey{AddressSpace: addressSpace, Subnet: nw.String(), ChildSubnet: subPool}, nw, ipr, pdf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
|
func (a *Allocator) insertBitMask(key SubnetKey, pool *net.IPNet) error {
|
||||||
|
|
|
@ -257,12 +257,15 @@ func (aSpace *addrSpace) New() datastore.KVObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aSpace *addrSpace) updatePoolDBOnAdd(k SubnetKey, nw *net.IPNet, ipr *AddressRange) (func() error, error) {
|
func (aSpace *addrSpace) updatePoolDBOnAdd(k SubnetKey, nw *net.IPNet, ipr *AddressRange, pdf bool) (func() error, error) {
|
||||||
aSpace.Lock()
|
aSpace.Lock()
|
||||||
defer aSpace.Unlock()
|
defer aSpace.Unlock()
|
||||||
|
|
||||||
// Check if already allocated
|
// Check if already allocated
|
||||||
if p, ok := aSpace.subnets[k]; ok {
|
if p, ok := aSpace.subnets[k]; ok {
|
||||||
|
if pdf {
|
||||||
|
return nil, types.InternalMaskableErrorf("predefined pool %s is already reserved", nw)
|
||||||
|
}
|
||||||
aSpace.incRefCount(p, 1)
|
aSpace.incRefCount(p, 1)
|
||||||
return func() error { return nil }, nil
|
return func() error { return nil }, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,11 +41,13 @@ const (
|
||||||
|
|
||||||
// resolver implements the Resolver interface
|
// resolver implements the Resolver interface
|
||||||
type resolver struct {
|
type resolver struct {
|
||||||
sb *sandbox
|
sb *sandbox
|
||||||
extDNS []string
|
extDNS []string
|
||||||
server *dns.Server
|
server *dns.Server
|
||||||
conn *net.UDPConn
|
conn *net.UDPConn
|
||||||
err error
|
tcpServer *dns.Server
|
||||||
|
tcpListen *net.TCPListener
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResolver creates a new instance of the Resolver
|
// NewResolver creates a new instance of the Resolver
|
||||||
|
@ -60,6 +62,7 @@ func (r *resolver) SetupFunc() func() {
|
||||||
return (func() {
|
return (func() {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
// DNS operates primarily on UDP
|
||||||
addr := &net.UDPAddr{
|
addr := &net.UDPAddr{
|
||||||
IP: net.ParseIP(resolverIP),
|
IP: net.ParseIP(resolverIP),
|
||||||
}
|
}
|
||||||
|
@ -72,9 +75,23 @@ func (r *resolver) SetupFunc() func() {
|
||||||
laddr := r.conn.LocalAddr()
|
laddr := r.conn.LocalAddr()
|
||||||
_, ipPort, _ := net.SplitHostPort(laddr.String())
|
_, ipPort, _ := net.SplitHostPort(laddr.String())
|
||||||
|
|
||||||
|
// Listen on a TCP as well
|
||||||
|
tcpaddr := &net.TCPAddr{
|
||||||
|
IP: net.ParseIP(resolverIP),
|
||||||
|
}
|
||||||
|
|
||||||
|
r.tcpListen, err = net.ListenTCP("tcp", tcpaddr)
|
||||||
|
if err != nil {
|
||||||
|
r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ltcpaddr := r.tcpListen.Addr()
|
||||||
|
_, tcpPort, _ := net.SplitHostPort(ltcpaddr.String())
|
||||||
rules := [][]string{
|
rules := [][]string{
|
||||||
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr.String()},
|
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr.String()},
|
||||||
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
||||||
|
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", ltcpaddr.String()},
|
||||||
|
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
|
@ -97,6 +114,12 @@ func (r *resolver) Start() error {
|
||||||
go func() {
|
go func() {
|
||||||
s.ActivateAndServe()
|
s.ActivateAndServe()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
tcpServer := &dns.Server{Handler: r, Listener: r.tcpListen}
|
||||||
|
r.tcpServer = tcpServer
|
||||||
|
go func() {
|
||||||
|
tcpServer.ActivateAndServe()
|
||||||
|
}()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +127,11 @@ func (r *resolver) Stop() {
|
||||||
if r.server != nil {
|
if r.server != nil {
|
||||||
r.server.Shutdown()
|
r.server.Shutdown()
|
||||||
}
|
}
|
||||||
|
if r.tcpServer != nil {
|
||||||
|
r.tcpServer.Shutdown()
|
||||||
|
}
|
||||||
r.conn = nil
|
r.conn = nil
|
||||||
|
r.tcpServer = nil
|
||||||
r.err = fmt.Errorf("setup not done yet")
|
r.err = fmt.Errorf("setup not done yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,9 +222,9 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
||||||
num = len(r.extDNS)
|
num = len(r.extDNS)
|
||||||
}
|
}
|
||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
log.Debugf("Querying ext dns %s for %s[%d]", r.extDNS[i], name, query.Question[0].Qtype)
|
log.Debugf("Querying ext dns %s:%s for %s[%d]", w.LocalAddr().Network(), r.extDNS[i], name, query.Question[0].Qtype)
|
||||||
|
|
||||||
c := &dns.Client{Net: "udp"}
|
c := &dns.Client{Net: w.LocalAddr().Network()}
|
||||||
addr := fmt.Sprintf("%s:%d", r.extDNS[i], 53)
|
addr := fmt.Sprintf("%s:%d", r.extDNS[i], 53)
|
||||||
|
|
||||||
resp, _, err = c.Exchange(query, addr)
|
resp, _, err = c.Exchange(query, addr)
|
||||||
|
|
|
@ -186,12 +186,6 @@ func (sb *sandbox) delete(force bool) error {
|
||||||
// Detach from all endpoints
|
// Detach from all endpoints
|
||||||
retain := false
|
retain := false
|
||||||
for _, ep := range sb.getConnectedEndpoints() {
|
for _, ep := range sb.getConnectedEndpoints() {
|
||||||
// endpoint in the Gateway network will be cleaned up
|
|
||||||
// when when sandbox no longer needs external connectivity
|
|
||||||
if ep.endpointInGWNetwork() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retain the sanbdox if we can't obtain the network from store.
|
// Retain the sanbdox if we can't obtain the network from store.
|
||||||
if _, err := c.getNetworkFromStore(ep.getNetwork().ID()); err != nil {
|
if _, err := c.getNetworkFromStore(ep.getNetwork().ID()); err != nil {
|
||||||
retain = true
|
retain = true
|
||||||
|
|
Загрузка…
Ссылка в новой задаче