Commit c8872a0b authored by Iustin Pop's avatar Iustin Pop
Browse files

Merge remote branch 'origin/master' into mogu

* origin/master:
  Fix burnin's verbose mode
  Final NEWS update and version increase for 2.0.4
  Encode the actual exception raised by LU execution
  Move the luxi error handling into
  Fix the confusing ssh/hostname message in node add
  Add man page for ganeti-cleaner
  Update NEWS file for version 2.0.4
  Automatically cleanup _temporary_ids at save
  Separate the computation of all config IDs
  Change config upgrade to be explicit
  Fix unittest breakage due to new test file
  Fix /proc/drbd parsing in presence of gaps
  repair-size: ensure child disks have sane sizes
  Fix yet another bug in LURepairDiskSizes
  Fix a bug in LURepairDiskSizes

	NEWS          (trivial, the RST change)
	lib/ (trivial, some small change in 2.0)
	lib/ (due to the cherry-picks and UUID changes in 2.1)
Signed-off-by: default avatarIustin Pop <>
parents e73a5804 88d31e5c
......@@ -235,6 +235,7 @@ EXTRA_DIST = \
man_MANS = \
man/ganeti.7 \
man/ganeti-cleaner.8 \
man/ganeti-masterd.8 \
man/ganeti-noded.8 \
man/ganeti-os-interface.7 \
......@@ -258,6 +259,7 @@ TEST_FILES = \
test/data/bdev-disk.txt \
test/data/bdev-net.txt \
test/data/proc_drbd8.txt \
test/data/proc_drbd80-emptyline.txt \
dist_TESTS = \
Version 2.0.4
- Fixed many wrong messages
- Fixed a few bugs related to the locking library
- Fixed MAC checking at instance creation time
- Fixed a DRBD parsing bug related to gaps in /proc/drbd
- Fixed a few issues related to signal handling in both daemons and
- Fixed the example startup script provided
- Fixed insserv dependencies in the example startup script (patch from
- Fixed handling of drained nodes in the iallocator framework
- Fixed handling of KERNEL_PATH parameter for xen-hvm (Debian bug
- Fixed error related to invalid job IDs in job polling
- Fixed job/opcode persistence on unclean master shutdown
- Fixed handling of partial job processing after unclean master
- Fixed error reporting from LUs, previously all errors were converted
into execution errors
- Fixed error reporting from burnin
- Decreased significantly the memory usage of the job queue
- Optimised slightly multi-job submission
- Optimised slightly opcode loading
- Backported the multi-job submit framework from the development
branch; multi-instance start and stop should be faster
- Added script to clean archived jobs after 21 days; this will reduce
the size of the queue directory
- Added some extra checks in disk size tracking
- Added an example ethers hook script
- Added a cluster parameter that prevents Ganeti from modifying of
- Added more node information to RAPI responses
- Added a “gnt-job watch” command that allows following the ouput of a
- Added a bind-address option to ganeti-rapi
- Added more checks to the configuration verify
- Enhanced the burnin script such that some operations can be retried
- Converted instance reinstall to multi-instance model
Version 2.0.3
# Configure script for Ganeti
m4_define([gnt_version_major], [2])
m4_define([gnt_version_minor], [0])
m4_define([gnt_version_revision], [3])
m4_define([gnt_version_revision], [4])
m4_define([gnt_version_suffix], [])
......@@ -803,6 +803,8 @@ class BaseDRBD(BlockDev):
results = {}
old_minor = old_line = None
for line in data:
if not line: # completely empty lines, as can be returned by drbd8.0+
lresult = lmatch.match(line)
if lresult is not None:
if old_minor is not None:
......@@ -1594,7 +1594,6 @@ class LURepairDiskSizes(NoHooksLU):
if full_name is None:
raise errors.OpPrereqError("Instance '%s' not known" % name)
self.needed_locks[locking.LEVEL_INSTANCE] = self.wanted_names
self.needed_locks = {
locking.LEVEL_NODE: [],
locking.LEVEL_INSTANCE: self.wanted_names,
......@@ -1624,6 +1623,29 @@ class LURepairDiskSizes(NoHooksLU):
self.wanted_instances = [self.cfg.GetInstanceInfo(name) for name
in self.wanted_names]
def _EnsureChildSizes(self, disk):
"""Ensure children of the disk have the needed disk size.
This is valid mainly for DRBD8 and fixes an issue where the
children have smaller disk size.
@param disk: an L{ganeti.objects.Disk} object
if disk.dev_type == constants.LD_DRBD8:
assert disk.children, "Empty children for DRBD8?"
fchild = disk.children[0]
mismatch = fchild.size < disk.size
if mismatch:
self.LogInfo("Child disk has size %d, parent %d, fixing",
fchild.size, disk.size)
fchild.size = disk.size
# and we recurse on this child only, not on the metadev
return self._EnsureChildSizes(fchild) or mismatch
return False
def Exec(self, feedback_fn):
"""Verify the size of cluster disks.
......@@ -1640,7 +1662,10 @@ class LURepairDiskSizes(NoHooksLU):
changed = []
for node, dskl in per_node_disks.items():
result = self.rpc.call_blockdev_getsizes(node, [v[2] for v in dskl])
newl = [v[2].Copy() for v in dskl]
for dsk in newl:
self.cfg.SetDiskID(dsk, node)
result = self.rpc.call_blockdev_getsizes(node, newl)
if result.fail_msg:
self.LogWarning("Failure in blockdev_getsizes call to node"
" %s, ignoring", node)
......@@ -1666,6 +1691,9 @@ class LURepairDiskSizes(NoHooksLU):
disk.size = size
changed.append((, idx, size))
if self._EnsureChildSizes(disk):
changed.append((, idx, disk.size))
return changed
......@@ -2861,7 +2889,8 @@ class LUAddNode(LogicalUnit):
nl_payload = result[verifier].payload[constants.NV_NODELIST]
if nl_payload:
for failed in nl_payload:
feedback_fn("ssh/hostname verification failed %s -> %s" %
feedback_fn("ssh/hostname verification failed"
" (checking from %s): %s" %
(verifier, nl_payload[failed]))
raise errors.OpExecError("ssh/hostname verification failed.")
......@@ -227,7 +227,12 @@ class SshRunner:
remotehostname = retval.stdout.strip()
if not remotehostname or remotehostname != node:
return False, "hostname mismatch, got %s" % remotehostname
if node.startswith(remotehostname + "."):
msg = "hostname not FQDN"
msg = "hostname mistmatch"
return False, ("%s: expected %s but got %s" %
(msg, node, remotehostname))
return True, "host matches"
......@@ -59,6 +59,10 @@
</citerefentry> (automatic instance restarter),
</citerefentry> (job queue cleaner),
<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
<!-- Please adjust the date whenever revising the manpage. -->
<!ENTITY dhdate "<date>February 11, 2009</date>">
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
allowed: see man(7), man(1). -->
<!ENTITY dhsection "<manvolnum>8</manvolnum>">
<!ENTITY dhucpackage "<refentrytitle>ganeti-cleaner</refentrytitle>">
<!ENTITY dhpackage "ganeti-cleaner">
<!ENTITY debian "<productname>Debian</productname>">
<!ENTITY gnu "<acronym>GNU</acronym>">
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
<!ENTITY footer SYSTEM "footer.sgml">
<holder>Google Inc.</holder>
<refmiscinfo>ganeti 2.0</refmiscinfo>
<refpurpose>ganeti job queue cleaner</refpurpose>
The <command>&dhpackage;</command> is a periodically run script to clean
old job files from the job queue archive.
<command>&dhpackage;</command> automatically removes all files older than
21 days from
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
GIT-hash: 5c9f89594553e32adb87d9638dce591782f947e3 build by, 2009-05-22 12:47:52
0: cs:Connected st:Primary/Secondary ds:UpToDate/UpToDate C r---
ns:78728316 nr:0 dw:77675644 dr:1277039 al:254 bm:270 lo:0 pe:0 ua:0 ap:0
resync: used:0/61 hits:65657 misses:135 starving:0 dirty:0 changed:135
act_log: used:0/257 hits:11378843 misses:254 starving:0 dirty:0 changed:254
1: cs:Unconfigured
2: cs:Unconfigured
5: cs:Unconfigured
6: cs:Unconfigured
......@@ -114,10 +114,13 @@ class TestDRBD8Status(testutils.GanetiTestCase):
"""Read in txt data"""
proc_data = self._TestDataFilename("proc_drbd8.txt")
proc80e_data = self._TestDataFilename("proc_drbd80-emptyline.txt")
proc83_data = self._TestDataFilename("proc_drbd83.txt")
self.proc_data = bdev.DRBD8._GetProcData(filename=proc_data)
self.proc80e_data = bdev.DRBD8._GetProcData(filename=proc80e_data)
self.proc83_data = bdev.DRBD8._GetProcData(filename=proc83_data)
self.mass_data = bdev.DRBD8._MassageProcData(self.proc_data)
self.mass80e_data = bdev.DRBD8._MassageProcData(self.proc80e_data)
self.mass83_data = bdev.DRBD8._MassageProcData(self.proc83_data)
def testIOErrors(self):
......@@ -131,6 +134,7 @@ class TestDRBD8Status(testutils.GanetiTestCase):
"""Test not-found-minor in /proc"""
self.failUnless(9 not in self.mass_data)
self.failUnless(9 not in self.mass83_data)
self.failUnless(3 not in self.mass80e_data)
def testLineNotMatch(self):
"""Test wrong line passed to DRBD8Status"""
......@@ -154,7 +158,7 @@ class TestDRBD8Status(testutils.GanetiTestCase):
def testMinor2(self):
"""Test unconfigured device"""
for data in [self.mass_data, self.mass83_data]:
for data in [self.mass_data, self.mass83_data, self.mass80e_data]:
stats = bdev.DRBD8Status(data[2])
......@@ -229,10 +229,10 @@ class Burner(object):
def Feedback(self, msg):
"""Acumulate feedback in our buffer."""
self._feed_buf.write("%s %s\n" % (time.ctime(utils.MergeTime(msg[0])),
formatted_msg = "%s %s" % (time.ctime(utils.MergeTime(msg[0])), msg[2])
self._feed_buf.write(formatted_msg + "\n")
if self.opts.verbose:
Log(msg, indent=3)
Log(formatted_msg, indent=3)
def MaybeRetry(self, retry_count, msg, fn, *args):
"""Possibly retry a given function execution.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment