Merge branch 'stable-2.15' into stable-2.16

* stable-2.15
  Cleanup more pylint/pep8/apidoc errors
  KVM: handle gracefully too old/too new psutil versions

Manually fix up merge conflicts.

Signed-off-by: Brian Foley <bpfoley@google.com>
Reviewed-by: Viktor Bachraty <vbachraty@google.com>
diff --git a/INSTALL b/INSTALL
index e33ab96..95f3019 100644
--- a/INSTALL
+++ b/INSTALL
@@ -42,7 +42,9 @@
 - `Paramiko <http://www.lag.net/paramiko/>`_, if you want to use
   ``ganeti-listrunner``
 - `psutil Python module <https://github.com/giampaolo/psutil>`_,
-  optional python package for supporting CPU pinning under KVM
+  optional python package for supporting CPU pinning under KVM, versions
+  2.x.x only; beware that versions from 2.0.0 to before 2.2.0 had a
+  number of file handle leaks, so running at least 2.2.0 is advised
 - `fdsend Python module <https://gitorious.org/python-fdsend>`_,
   optional Python package for supporting NIC hotplugging under KVM
 - `qemu-img <http://qemu.org/>`_, if you want to use ``ovfconverter``
diff --git a/lib/cli.py b/lib/cli.py
index a470ffa..362f2ae 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -747,7 +747,7 @@
         timer += constants.CLI_WFJC_FREQUENCY
     else:
       result = cbs.WaitForJobChangeOnce(job_id, ["status"], prev_job_info,
-                                      prev_logmsg_serial, timeout=update_freq)
+                                        prev_logmsg_serial, timeout=update_freq)
     if not result:
       # job not found, go away!
       raise errors.JobLost("Job with id %s lost" % job_id)
@@ -906,6 +906,7 @@
     """
     return self.cl.CancelJob(job_id)
 
+
 class FeedbackFnJobPollReportCb(JobPollReportCbBase):
   def __init__(self, feedback_fn):
     """Initializes this class.
diff --git a/lib/cmdlib/cluster/verify.py b/lib/cmdlib/cluster/verify.py
index d94c5d1..0036f69 100644
--- a/lib/cmdlib/cluster/verify.py
+++ b/lib/cmdlib/cluster/verify.py
@@ -109,8 +109,8 @@
     @type error_descriptor: tuple (string, string, string)
     @param error_descriptor: triplet describing the error (object_type,
         code, description)
-    @type obj_name: string
-    @param obj_name: name of object (instance, node ..) the error relates to
+    @type object_name: string
+    @param object_name: name of object (instance, node ..) the error relates to
     @type message_list: list of strings
     @param message_list: body of error messages
     @type log_type: string
@@ -133,7 +133,7 @@
             log_type, error_code, object_type, object_name, msg))
     else:
       if not object_name:
-        object_name  = ""
+        object_name = ""
       for msg in message_list:
         prefixed_list.append("  - %s: %s %s: %s" % (
             log_type, object_type, object_name, msg))
diff --git a/lib/hypervisor/hv_kvm/__init__.py b/lib/hypervisor/hv_kvm/__init__.py
index 1e89c82..580606b 100644
--- a/lib/hypervisor/hv_kvm/__init__.py
+++ b/lib/hypervisor/hv_kvm/__init__.py
@@ -45,7 +45,17 @@
 from bitarray import bitarray
 try:
   import psutil   # pylint: disable=F0401
+  if psutil.version_info < (2, 0, 0):
+    # The psutil version seems too old, we ignore it
+    psutil_err = "too old (2.x.x needed, %s found)" % psutil.__version__
+    psutil = None
+  elif psutil.version_info >= (3,):
+    psutil_err = "too new (2.x.x needed, %s found)" % psutil.__version__
+    psutil = None
+  else:
+    psutil_err = "<no error>"
 except ImportError:
+  psutil_err = "not found"
   psutil = None
 try:
   import fdsend   # pylint: disable=F0401
@@ -885,11 +895,14 @@
 
     """
     if psutil is None:
-      raise errors.HypervisorError("psutil Python package not"
-                                   " found; cannot use CPU pinning under KVM")
+      raise errors.HypervisorError("psutil Python package %s"
+                                   "; cannot use CPU pinning"
+                                   " under KVM" % psutil_err)
 
     target_process = psutil.Process(process_id)
     if cpus == constants.CPU_PINNING_OFF:
+      # we checked this at import time
+      # pylint: disable=E1101
       target_process.set_cpu_affinity(range(psutil.cpu_count()))
     else:
       target_process.set_cpu_affinity(cpus)
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index 8916004..14c12ac 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -200,6 +200,7 @@
 
   return inst
 
+
 def _CheckIfConnectionDropped(sock):
   """Utility function to monitor the state of an open connection.
 
diff --git a/src/Ganeti/Objects/Disk.hs b/src/Ganeti/Objects/Disk.hs
index 01e798d..a03ba23 100644
--- a/src/Ganeti/Objects/Disk.hs
+++ b/src/Ganeti/Objects/Disk.hs
@@ -81,7 +81,7 @@
   showsPrec _ (LogicalVolume g v) =
     showString g . showString "/" . showString v
 
--- | Check the constraints for a VG/LV names (except the \@\/dev\/\@ check).
+-- | Check the constraints for VG\/LV names (except the @\/dev\/@ check).
 instance Validatable LogicalVolume where
   validate (LogicalVolume g v) = do
       let vgn = "Volume group name"
diff --git a/test/py/mocks.py b/test/py/mocks.py
index 406caca..b48125b 100644
--- a/test/py/mocks.py
+++ b/test/py/mocks.py
@@ -113,6 +113,7 @@
 
 class FakeContext(object):
   """Fake context object"""
+  # pylint: disable=W0613
 
   def __init__(self):
     self.cfg = FakeConfig()
@@ -124,9 +125,10 @@
   def GetRpc(self, cfg):
     return None
 
-  def GetWConfdContext(self, _ec_id):
+  def GetWConfdContext(self, ec_id):
     return (None, None, None)
 
+
 class FakeGetentResolver(object):
   """Fake runtime.GetentResolver"""
 
@@ -154,6 +156,7 @@
   def LookupGid(self, gid):
     return "group%s" % gid
 
+
 class FakeLU(object):
   HPATH = "fake-lu"
   HTYPE = None
@@ -161,7 +164,7 @@
   def __init__(self, processor, op, cfg, rpc_runner, prereq_err):
     self.proc = processor
     self.cfg = cfg
-    self.op  = op
+    self.op = op
     self.rpc = rpc_runner
     self.prereq_err = prereq_err
 
@@ -170,7 +173,7 @@
     self.dont_collate_locks = dict.fromkeys(locking.LEVELS, False)
     self.add_locks = {}
 
-    self.LogWarning = processor.LogWarning
+    self.LogWarning = processor.LogWarning # pylint: disable=C0103
 
   def CheckArguments(self):
     pass
@@ -184,7 +187,6 @@
   def CheckPrereq(self):
     if self.prereq_err:
       raise self.prereq_err
-    pass
 
   def Exec(self, feedback_fn):
     pass
@@ -196,7 +198,9 @@
     return {}
 
   def PreparePostHookNodes(self, post_hook_node_uuids):
+    # pylint: disable=W0613
     return []
 
   def HooksCallBack(self, phase, hook_results, feedback_fn, lu_result):
+    # pylint: disable=W0613
     return lu_result