Просмотр исходного кода

Merge pull request #149 from mrjana/cnm_integ

Update resolvconf and iptables packages
Madhu Venugopal 10 лет назад
Родитель
Сommit
ab9dfa2b1e

+ 7 - 11
libnetwork/pkg/iptables/firewalld.go

@@ -38,19 +38,18 @@ var (
 )
 
 // FirewalldInit initializes firewalld management code.
-func FirewalldInit() {
+func FirewalldInit() error {
 	var err error
 
-	connection, err = newConnection()
-
-	if err != nil {
-		logrus.Errorf("Failed to connect to D-Bus system bus: %s", err)
+	if connection, err = newConnection(); err != nil {
+		return fmt.Errorf("Failed to connect to D-Bus system bus: %v", err)
 	}
 	if connection != nil {
 		go signalHandler()
 	}
 
 	firewalldRunning = checkRunning()
+	return nil
 }
 
 // New() establishes a connection to the system bus.
@@ -151,7 +150,6 @@ func checkRunning() bool {
 		logrus.Infof("Firewalld running: %t", err == nil)
 		return err == nil
 	}
-	logrus.Info("Firewalld not running")
 	return false
 }
 
@@ -160,10 +158,8 @@ func Passthrough(ipv IPV, args ...string) ([]byte, error) {
 	var output string
 
 	logrus.Debugf("Firewalld passthrough: %s, %s", ipv, args)
-	err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output)
-	if output != "" {
-		logrus.Debugf("passthrough output: %s", output)
+	if err := connection.sysobj.Call(dbusInterface+".direct.passthrough", 0, ipv, args).Store(&output); err != nil {
+		return nil, err
 	}
-
-	return []byte(output), err
+	return []byte(output), nil
 }

+ 6 - 0
libnetwork/pkg/iptables/iptables.go

@@ -8,6 +8,7 @@ import (
 	"regexp"
 	"strconv"
 	"strings"
+	"sync"
 
 	"github.com/Sirupsen/logrus"
 )
@@ -36,6 +37,8 @@ const (
 var (
 	iptablesPath  string
 	supportsXlock = false
+	// used to lock iptables commands if xtables lock is not supported
+	bestEffortLock sync.Mutex
 	//ErrIptablesNotFound is returned when the rule is not found.
 	ErrIptablesNotFound = errors.New("Iptables not found")
 )
@@ -303,6 +306,9 @@ func Raw(args ...string) ([]byte, error) {
 	}
 	if supportsXlock {
 		args = append([]string{"--wait"}, args...)
+	} else {
+		bestEffortLock.Lock()
+		defer bestEffortLock.Unlock()
 	}
 
 	logrus.Debugf("%s, %v", iptablesPath, args)

+ 40 - 0
libnetwork/pkg/iptables/iptables_test.go

@@ -5,6 +5,7 @@ import (
 	"os/exec"
 	"strconv"
 	"strings"
+	"sync"
 	"testing"
 
 	_ "github.com/docker/libnetwork/netutils"
@@ -171,6 +172,45 @@ func TestOutput(t *testing.T) {
 	}
 }
 
+func TestConcurrencyWithWait(t *testing.T) {
+	RunConcurrencyTest(t, true)
+}
+
+func TestConcurrencyNoWait(t *testing.T) {
+	RunConcurrencyTest(t, false)
+}
+
+// Runs 10 concurrent rule additions. This will fail if iptables
+// is actually invoked simultaneously without --wait.
+// Note that if iptables does not support the xtable lock on this
+// system, then allowXlock has no effect -- it will always be off.
+func RunConcurrencyTest(t *testing.T, allowXlock bool) {
+	var wg sync.WaitGroup
+
+	if !allowXlock && supportsXlock {
+		supportsXlock = false
+		defer func() { supportsXlock = true }()
+	}
+
+	ip := net.ParseIP("192.168.1.1")
+	port := 1234
+	dstAddr := "172.17.0.1"
+	dstPort := 4321
+	proto := "tcp"
+
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			err := natChain.Forward(Append, ip, port, proto, dstAddr, dstPort)
+			if err != nil {
+				t.Fatal(err)
+			}
+		}()
+	}
+	wg.Wait()
+}
+
 func TestCleanup(t *testing.T) {
 	var err error
 	var rules []byte

+ 17 - 0
libnetwork/pkg/resolvconf/dns/resolvconf.go

@@ -0,0 +1,17 @@
+package dns
+
+import (
+	"regexp"
+)
+
+// IPLocalhost is a regex patter for localhost IP address range.
+const IPLocalhost = `((127\.([0-9]{1,3}.){2}[0-9]{1,3})|(::1))`
+
+var localhostIPRegexp = regexp.MustCompile(IPLocalhost)
+
+// IsLocalhost returns true if ip matches the localhost IP regular expression.
+// Used for determining if nameserver settings are being passed which are
+// localhost addresses
+func IsLocalhost(ip string) bool {
+	return localhostIPRegexp.MatchString(ip)
+}

+ 2 - 10
libnetwork/pkg/resolvconf/resolvconf.go

@@ -10,6 +10,7 @@ import (
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/ioutils"
+	"github.com/docker/libnetwork/pkg/resolvconf/dns"
 )
 
 var (
@@ -24,10 +25,8 @@ var (
 	// For readability and sufficiency for Docker purposes this seemed more reasonable than a
 	// 1000+ character regexp with exact and complete IPv6 validation
 	ipv6Address = `([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})`
-	ipLocalhost = `((127\.([0-9]{1,3}.){2}[0-9]{1,3})|(::1))`
 
-	localhostIPRegexp = regexp.MustCompile(ipLocalhost)
-	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + ipLocalhost + `\s*\n*`)
+	localhostNSRegexp = regexp.MustCompile(`(?m)^nameserver\s+` + dns.IPLocalhost + `\s*\n*`)
 	nsIPv6Regexp      = regexp.MustCompile(`(?m)^nameserver\s+` + ipv6Address + `\s*\n*`)
 	nsRegexp          = regexp.MustCompile(`^\s*nameserver\s*((` + ipv4Address + `)|(` + ipv6Address + `))\s*$`)
 	searchRegexp      = regexp.MustCompile(`^\s*search\s*(([^\s]+\s*)*)$`)
@@ -128,13 +127,6 @@ func getLines(input []byte, commentMarker []byte) [][]byte {
 	return output
 }
 
-// IsLocalhost returns true if ip matches the localhost IP regular expression.
-// Used for determining if nameserver settings are being passed which are
-// localhost addresses
-func IsLocalhost(ip string) bool {
-	return localhostIPRegexp.MatchString(ip)
-}
-
 // GetNameservers returns nameservers (if any) listed in /etc/resolv.conf
 func GetNameservers(resolvConf []byte) []string {
 	nameservers := []string{}