From f965260c2a14202cd7558e90f3939ecc8ff1dec3 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Fri, 22 Jul 2011 13:27:05 +0200
Subject: [PATCH] gnt-instance info: Return static info if node offline
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Before this patch β€œgnt-instance info” would fail with the error message
β€œError checking node $node: Node is marked offline” if the instance's
primary node is marked offline and the user didn't explicitely request
static information only. With this patch the LU will automatically
return static information if the instance's primary node is marked
offline.

Some explicit loops are changed to map().

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/client/gnt_instance.py | 17 ++++++++---------
 lib/cmdlib.py              | 22 +++++++++++++++-------
 2 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/lib/client/gnt_instance.py b/lib/client/gnt_instance.py
index 7a685140c..402629d09 100644
--- a/lib/client/gnt_instance.py
+++ b/lib/client/gnt_instance.py
@@ -985,7 +985,7 @@ def _FormatLogicalID(dev_type, logical_id, roman):
   return data
 
 
-def _FormatBlockDevInfo(idx, top_level, dev, static, roman):
+def _FormatBlockDevInfo(idx, top_level, dev, roman):
   """Show block device information.
 
   This is only used by L{ShowInstanceConfig}, but it's too big to be
@@ -997,9 +997,6 @@ def _FormatBlockDevInfo(idx, top_level, dev, static, roman):
   @param top_level: if this a top-level disk?
   @type dev: dict
   @param dev: dictionary with disk information
-  @type static: boolean
-  @param static: wheter the device information doesn't contain
-      runtime information but only static data
   @type roman: boolean
   @param roman: whether to try to use roman integers
   @return: a list of either strings, tuples or lists
@@ -1087,15 +1084,17 @@ def _FormatBlockDevInfo(idx, top_level, dev, static, roman):
   elif dev["physical_id"] is not None:
     data.append("physical_id:")
     data.append([dev["physical_id"]])
-  if not static:
+
+  if dev["pstatus"]:
     data.append(("on primary", helper(dev["dev_type"], dev["pstatus"])))
-  if dev["sstatus"] and not static:
+
+  if dev["sstatus"]:
     data.append(("on secondary", helper(dev["dev_type"], dev["sstatus"])))
 
   if dev["children"]:
     data.append("child devices:")
     for c_idx, child in enumerate(dev["children"]):
-      data.append(_FormatBlockDevInfo(c_idx, False, child, static, roman))
+      data.append(_FormatBlockDevInfo(c_idx, False, child, roman))
   d1.append(data)
   return d1
 
@@ -1169,7 +1168,7 @@ def ShowInstanceConfig(opts, args):
     buf.write("Creation time: %s\n" % utils.FormatTime(instance["ctime"]))
     buf.write("Modification time: %s\n" % utils.FormatTime(instance["mtime"]))
     buf.write("State: configured to be %s" % instance["config_state"])
-    if not opts.static:
+    if instance["run_state"]:
       buf.write(", actual state is %s" % instance["run_state"])
     buf.write("\n")
     ##buf.write("Considered for memory checks in cluster verify: %s\n" %
@@ -1223,7 +1222,7 @@ def ShowInstanceConfig(opts, args):
     buf.write("  Disks:\n")
 
     for idx, device in enumerate(instance["disks"]):
-      _FormatList(buf, _FormatBlockDevInfo(idx, True, device, opts.static,
+      _FormatList(buf, _FormatBlockDevInfo(idx, True, device,
                   opts.roman_integers), 2)
 
   ToStdout(buf.getvalue().rstrip('\n'))
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 0cbe51559..25e3ad5c0 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -10199,8 +10199,9 @@ class LUInstanceQueryData(NoHooksLU):
     dev_sstatus = self._ComputeBlockdevStatus(snode, instance.name, dev)
 
     if dev.children:
-      dev_children = [self._ComputeDiskStatus(instance, snode, child)
-                      for child in dev.children]
+      dev_children = map(compat.partial(self._ComputeDiskStatus,
+                                        instance, snode),
+                         dev.children)
     else:
       dev_children = []
 
@@ -10223,7 +10224,15 @@ class LUInstanceQueryData(NoHooksLU):
     cluster = self.cfg.GetClusterInfo()
 
     for instance in self.wanted_instances:
-      if not self.op.static:
+      pnode = self.cfg.GetNodeInfo(instance.primary_node)
+
+      if self.op.static or pnode.offline:
+        remote_state = None
+        if pnode.offline:
+          self.LogWarning("Primary node %s is marked offline, returning static"
+                          " information only for instance %s" %
+                          (pnode.name, instance.name))
+      else:
         remote_info = self.rpc.call_instance_info(instance.primary_node,
                                                   instance.name,
                                                   instance.hypervisor)
@@ -10233,15 +10242,14 @@ class LUInstanceQueryData(NoHooksLU):
           remote_state = "up"
         else:
           remote_state = "down"
-      else:
-        remote_state = None
+
       if instance.admin_up:
         config_state = "up"
       else:
         config_state = "down"
 
-      disks = [self._ComputeDiskStatus(instance, None, device)
-               for device in instance.disks]
+      disks = map(compat.partial(self._ComputeDiskStatus, instance, None),
+                  instance.disks)
 
       result[instance.name] = {
         "name": instance.name,
-- 
GitLab