diff --git a/Makefile.am b/Makefile.am index 4a61f51119eff6cfda6018b32ce3d60039cbe489..12a486066bc9052db297c937587056e16f5c1eb4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -348,10 +348,11 @@ maninput = \ $(patsubst %.html,%.html.in,$(manhtml)) TEST_FILES = \ - test/data/bdev-both.txt \ - test/data/bdev-8.3-both.txt \ - test/data/bdev-disk.txt \ - test/data/bdev-net.txt \ + test/data/bdev-drbd-8.0.txt \ + test/data/bdev-drbd-8.3.txt \ + test/data/bdev-drbd-disk.txt \ + test/data/bdev-drbd-net-ip4.txt \ + test/data/bdev-drbd-net-ip6.txt \ test/data/cert1.pem \ test/data/proc_drbd8.txt \ test/data/proc_drbd80-emptyline.txt \ diff --git a/lib/bdev.py b/lib/bdev.py index f2b96f4878c0a920e602da6a3db1c5882f04a5e5..e941362fa8b5641a3a903f0d42385934d36f6a6a 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -1079,7 +1079,10 @@ class DRBD8(BaseDRBD): # pyparsing setup lbrace = pyp.Literal("{").suppress() rbrace = pyp.Literal("}").suppress() + lbracket = pyp.Literal("[").suppress() + rbracket = pyp.Literal("]").suppress() semi = pyp.Literal(";").suppress() + colon = pyp.Literal(":").suppress() # this also converts the value to an int number = pyp.Word(pyp.nums).setParseAction(lambda s, l, t: int(t[0])) @@ -1092,19 +1095,19 @@ class DRBD8(BaseDRBD): # value types value = pyp.Word(pyp.alphanums + '_-/.:') quoted = dbl_quote + pyp.CharsNotIn('"') + dbl_quote - addr_type = (pyp.Optional(pyp.Literal("ipv4")).suppress() + - pyp.Optional(pyp.Literal("ipv6")).suppress()) - addr_port = (addr_type + pyp.Word(pyp.nums + '.') + - pyp.Literal(':').suppress() + number) + ipv4_addr = (pyp.Optional(pyp.Literal("ipv4")).suppress() + + pyp.Word(pyp.nums + ".") + colon + number) + ipv6_addr = (pyp.Optional(pyp.Literal("ipv6")).suppress() + + pyp.Optional(lbracket) + pyp.Word(pyp.hexnums + ":") + + pyp.Optional(rbracket) + colon + number) # meta device, extended syntax - meta_value = ((value ^ quoted) + pyp.Literal('[').suppress() + - number + pyp.Word(']').suppress()) + meta_value = ((value ^ quoted) + lbracket + number + rbracket) # device name, extended syntax device_value = pyp.Literal("minor").suppress() + number # a statement stmt = (~rbrace + keyword + ~lbrace + - pyp.Optional(addr_port ^ value ^ quoted ^ meta_value ^ + pyp.Optional(ipv4_addr ^ ipv6_addr ^ value ^ quoted ^ meta_value ^ device_value) + pyp.Optional(defa) + semi + pyp.Optional(pyp.restOfLine).suppress()) @@ -1280,8 +1283,22 @@ class DRBD8(BaseDRBD): # about its peer. cls._SetMinorSyncSpeed(minor, constants.SYNC_SPEED) + if utils.IsValidIP6(lhost): + if not utils.IsValidIP6(rhost): + _ThrowError("drbd%d: can't connect ip %s to ip %s" % + (minor, lhost, rhost)) + family = "ipv6" + elif utils.IsValidIP4(lhost): + if not utils.IsValidIP4(rhost): + _ThrowError("drbd%d: can't connect ip %s to ip %s" % + (minor, lhost, rhost)) + family = "ipv4" + else: + _ThrowError("drbd%d: Invalid ip %s" % (minor, lhost)) + args = ["drbdsetup", cls._DevPath(minor), "net", - "%s:%s" % (lhost, lport), "%s:%s" % (rhost, rport), protocol, + "%s:%s:%s" % (family, lhost, lport), + "%s:%s:%s" % (family, rhost, rport), protocol, "-A", "discard-zero-changes", "-B", "consensus", "--create-device", diff --git a/test/data/bdev-both.txt b/test/data/bdev-drbd-8.0.txt similarity index 100% rename from test/data/bdev-both.txt rename to test/data/bdev-drbd-8.0.txt diff --git a/test/data/bdev-8.3-both.txt b/test/data/bdev-drbd-8.3.txt similarity index 100% rename from test/data/bdev-8.3-both.txt rename to test/data/bdev-drbd-8.3.txt diff --git a/test/data/bdev-disk.txt b/test/data/bdev-drbd-disk.txt similarity index 100% rename from test/data/bdev-disk.txt rename to test/data/bdev-drbd-disk.txt diff --git a/test/data/bdev-net.txt b/test/data/bdev-drbd-net-ip4.txt similarity index 100% rename from test/data/bdev-net.txt rename to test/data/bdev-drbd-net-ip4.txt diff --git a/test/data/bdev-drbd-net-ip6.txt b/test/data/bdev-drbd-net-ip6.txt new file mode 100644 index 0000000000000000000000000000000000000000..87da1a50b8be1a78ede063d629553f2507767d7c --- /dev/null +++ b/test/data/bdev-drbd-net-ip6.txt @@ -0,0 +1,31 @@ +net { + timeout 60 _is_default; # 1/10 seconds + max-epoch-size 2048 _is_default; + max-buffers 2048 _is_default; + unplug-watermark 128 _is_default; + connect-int 10 _is_default; # seconds + ping-int 10 _is_default; # seconds + sndbuf-size 0 _is_default; # bytes + rcvbuf-size 0 _is_default; # bytes + ko-count 0 _is_default; + cram-hmac-alg "md5"; + shared-secret "a6526cb6118297c9c82c7003924e236ceac0d867"; + after-sb-0pri discard-zero-changes; + after-sb-1pri consensus; + after-sb-2pri disconnect _is_default; + rr-conflict disconnect _is_default; + ping-timeout 5 _is_default; # 1/10 seconds +} +syncer { + rate 61440k; # bytes/second + after -1 _is_default; + al-extents 257; +} +protocol C; +_this_host { + device minor 0; + address ipv6 [2001:db8:65::1]:11048; +} +_remote_host { + address ipv6 [2001:db8:66::1]:11048; +} diff --git a/test/ganeti.bdev_unittest.py b/test/ganeti.bdev_unittest.py index 19e1b8a53e314a98cf428760a9194f6ee25a5d8a..1e4460500744f37e8c5c539958db81ed1b52b1cd 100755 --- a/test/ganeti.bdev_unittest.py +++ b/test/ganeti.bdev_unittest.py @@ -62,9 +62,9 @@ class TestDRBD8Runner(testutils.GanetiTestCase): """Test drbdsetup show parser creation""" bdev.DRBD8._GetShowParser() - def testParserBoth80(self): - """Test drbdsetup show parser for disk and network""" - data = self._ReadTestData("bdev-both.txt") + def testParser80(self): + """Test drbdsetup show parser for disk and network version 8.0""" + data = self._ReadTestData("bdev-drbd-8.0.txt") result = bdev.DRBD8._GetDevInfo(data) self.failUnless(self._has_disk(result, "/dev/xenvg/test.data", "/dev/xenvg/test.meta"), @@ -73,20 +73,20 @@ class TestDRBD8Runner(testutils.GanetiTestCase): ("192.168.1.2", 11000)), "Wrong network info (8.0.x)") - def testParserBoth83(self): - """Test drbdsetup show parser for disk and network""" - data = self._ReadTestData("bdev-8.3-both.txt") + def testParser83(self): + """Test drbdsetup show parser for disk and network version 8.3""" + data = self._ReadTestData("bdev-drbd-8.3.txt") result = bdev.DRBD8._GetDevInfo(data) self.failUnless(self._has_disk(result, "/dev/xenvg/test.data", "/dev/xenvg/test.meta"), "Wrong local disk info") self.failUnless(self._has_net(result, ("192.168.1.1", 11000), ("192.168.1.2", 11000)), - "Wrong network info (8.2.x)") + "Wrong network info (8.0.x)") - def testParserNet(self): - """Test drbdsetup show parser for disk and network""" - data = self._ReadTestData("bdev-net.txt") + def testParserNetIP4(self): + """Test drbdsetup show parser for IPv4 network""" + data = self._ReadTestData("bdev-drbd-net-ip4.txt") result = bdev.DRBD8._GetDevInfo(data) self.failUnless(("local_dev" not in result and "meta_dev" not in result and @@ -94,11 +94,23 @@ class TestDRBD8Runner(testutils.GanetiTestCase): "Should not find local disk info") self.failUnless(self._has_net(result, ("192.168.1.1", 11002), ("192.168.1.2", 11002)), - "Wrong network info") + "Wrong network info (IPv4)") + + def testParserNetIP6(self): + """Test drbdsetup show parser for IPv6 network""" + data = self._ReadTestData("bdev-drbd-net-ip6.txt") + result = bdev.DRBD8._GetDevInfo(data) + self.failUnless(("local_dev" not in result and + "meta_dev" not in result and + "meta_index" not in result), + "Should not find local disk info") + self.failUnless(self._has_net(result, ("2001:db8:65::1", 11048), + ("2001:db8:66::1", 11048)), + "Wrong network info (IPv6)") def testParserDisk(self): - """Test drbdsetup show parser for disk and network""" - data = self._ReadTestData("bdev-disk.txt") + """Test drbdsetup show parser for disk""" + data = self._ReadTestData("bdev-drbd-disk.txt") result = bdev.DRBD8._GetDevInfo(data) self.failUnless(self._has_disk(result, "/dev/xenvg/test.data", "/dev/xenvg/test.meta"),