- 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
-------------
# 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],
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
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::
#
#
-# 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
_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"
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
#
#
-# 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
error = GetEncodedError(result)
if error:
(errcls, args) = error
- raise errcls(args)
+ # pylint: disable=W0142
+ raise errcls(*args)
#!/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
("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",