diff --git a/NEWS b/NEWS index 37527ebe1933875d9f13b495aec4607e44403bef..7b4caa4a4a195ad79390a7d62ce4a7f1853cbe59 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,45 @@ Version 2.6.0 beta1 - The QA scripts now depend on Python 2.5 or above +Version 2.5.1 +------------- + +*(Released Fri, 11 May 2012)* + +A small bugfix release. + +The main issues solved are on the topic of compatibility with newer LVM +releases: + +- fixed parsing of ``lv_attr`` field +- adapted to new ``vgreduce --removemissing`` behaviour where sometimes + the ``--force`` flag is needed + +Also on the topic of compatibility, ``tools/lvmstrap`` has been changed +to accept kernel 3.x too (was hardcoded to 2.6.*). + +A regression present in 2.5.0 that broke handling (in the gnt-* scripts) +of hook results and that also made display of other errors suboptimal +was fixed; the code behaves now like 2.4 and earlier. + +Another change in 2.5, the cleanup of the OS scripts environment, is too +aggressive: it removed even the ``PATH`` variable, which requires the OS +scripts to *always* need to export it. Since this is a bit too strict, +we now export a minimal PATH, the same that we export for hooks. + +The fix for issue 201 (Preserve bridge MTU in KVM ifup script) was +integrated into this release. + +Finally, a few other miscellaneous changes were done (no new features, +just small improvements): + +- Fix ``gnt-group --help`` display +- Fix hardcoded Xen kernel path +- Fix grow-disk handling of invalid units +- Update synopsis for ``gnt-cluster repair-disk-sizes`` +- Accept both PUT and POST in noded (makes future upgrade to 2.6 easier) + + Version 2.5.0 ------------- diff --git a/configure.ac b/configure.ac index fabf8f21a3fe8b2fee2c6300903a807e04cc1939..c85bfacc0eddaa70f5ce3d02c15e08a2269dd5c9 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Configure script for Ganeti m4_define([gnt_version_major], [2]) m4_define([gnt_version_minor], [5]) -m4_define([gnt_version_revision], [0]) +m4_define([gnt_version_revision], [1]) m4_define([gnt_version_suffix], []) m4_define([gnt_version_full], m4_format([%d.%d.%d%s], diff --git a/doc/install.rst b/doc/install.rst index 760a74ee4d0efa6b560ae7d0c401cea6fd1433b9..8abbfb570ac05e4a1a9b70a1aa7f728190620537 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -449,6 +449,26 @@ outside of ganeti. The vif scripts will only add /32 routes to your instances, through their interface, in the table you specified (under KVM, and in the main table under Xen). +.. admonition:: Bridging issues with certain kernels + + Some kernel versions (e.g. 2.6.32) have an issue where the bridge + will automatically change its ``MAC`` address to the lower-numbered + slave on port addition and removal. This means that, depending on + the ``MAC`` address of the actual NIC on the node and the addresses + of the instances, it could be that starting, stopping or migrating + instances will lead to timeouts due to the address of the bridge + (and thus node itself) changing. + + To prevent this, it's enough to set the bridge manually to a + specific ``MAC`` address, which will disable this automatic address + change. In Debian, this can be done as follows in the bridge + configuration snippet:: + + up ip link set addr $(cat /sys/class/net/$IFACE/address) dev $IFACE + + which will "set" the bridge address to the initial one, disallowing + changes. + .. admonition:: Bridging under Debian The recommended way to configure the Xen bridge is to edit your @@ -465,6 +485,8 @@ KVM, and in the main table under Xen). bridge_ports eth0 bridge_stp off bridge_fd 0 + # example for setting manually the bridge address to the eth0 NIC + up ip link set addr $(cat /sys/class/net/eth0/address) dev $IFACE The following commands need to be executed on the local console:: diff --git a/lib/backend.py b/lib/backend.py index 338a30d385b33b585a6b0c04e3df45c7ca8334ca..51a06bbfaa3e28d3df162bf72f83e725ac674b8d 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -79,7 +79,7 @@ _IES_PID_FILE = "pid" _IES_CA_FILE = "ca" #: Valid LVS output line regex -_LVSLINE_REGEX = re.compile("^ *([^|]+)\|([^|]+)\|([0-9.]+)\|([^|]{6})\|?$") +_LVSLINE_REGEX = re.compile("^ *([^|]+)\|([^|]+)\|([0-9.]+)\|([^|]{6,})\|?$") # Actions for the master setup script _MASTER_START = "start" @@ -2373,6 +2373,11 @@ def OSCoreEnv(os_name, inst_os, os_params, debug=0): for pname, pvalue in os_params.items(): result["OSP_%s" % pname.upper()] = pvalue + # Set a default path otherwise programs called by OS scripts (or + # even hooks called from OS scripts) might break, and we don't want + # to have each script require setting a PATH variable + result["PATH"] = constants.HOOKS_PATH + return result diff --git a/lib/errors.py b/lib/errors.py index 27d2fccf7e2728194c27df731589a9736dece252..ca3e4d80118b7fb3402638ea067368b09dae1e87 100644 --- a/lib/errors.py +++ b/lib/errors.py @@ -1,7 +1,7 @@ # # -# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc. +# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -502,4 +502,5 @@ def MaybeRaise(result): error = GetEncodedError(result) if error: (errcls, args) = error - raise errcls(args) + # pylint: disable=W0142 + raise errcls(*args) diff --git a/test/ganeti.errors_unittest.py b/test/ganeti.errors_unittest.py index ec25912c60da75ed8a74396c14a4d6fbd0f52fc8..f10f661c7ae0b03822da571311d079947a101f07 100755 --- a/test/ganeti.errors_unittest.py +++ b/test/ganeti.errors_unittest.py @@ -1,7 +1,7 @@ #!/usr/bin/python # -# Copyright (C) 2010 Google Inc. +# Copyright (C) 2010, 2012 Google Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -53,14 +53,25 @@ class TestErrors(testutils.GanetiTestCase): ("GenericError", (True, 100, "foo", ["x", "y"]))) def testMaybeRaise(self): + testvals = [None, 1, 2, 3, "Hello World", (1, ), (1, 2, 3), + ("NoErrorClassName", []), ("NoErrorClassName", None), + ("GenericError", [1, 2, 3], None), ("GenericError", 1)] # These shouldn't raise - for i in [None, 1, 2, 3, "Hello World", (1, ), (1, 2, 3), - ("NoErrorClassName", []), ("NoErrorClassName", None), - ("GenericError", [1, 2, 3], None), ("GenericError", 1)]: + for i in testvals: errors.MaybeRaise(i) self.assertRaises(errors.GenericError, errors.MaybeRaise, ("GenericError", ["Hello"])) + # Check error encoding + for i in testvals: + src = errors.GenericError(i) + try: + errors.MaybeRaise(errors.EncodeException(src)) + except errors.GenericError, dst: + self.assertEqual(src.args, dst.args) + self.assertEqual(src.__class__, dst.__class__) + else: + self.fail("Exception %s not raised" % repr(src)) def testGetEncodedError(self): self.assertEqualValues(errors.GetEncodedError(["GenericError",