Use new query function for exports in gnt-backup
[ganeti-local] / scripts / gnt-os
index 82c2671..e4041c7 100755 (executable)
@@ -28,119 +28,27 @@ from ganeti import logger
 from ganeti import objects
 from ganeti import utils
 from ganeti import errors
-
-
-def _DiagnoseOSValid(obj):
-  """Verify whether an OS diagnose object represents a valid OS
-
-    Args:
-      obj: an diagnostic object as returned by OpDiagnoseOS
-
-    Returns:
-      bool: OS validity status
-  """
-
-  if isinstance(obj, objects.OS):
-    return True
-  elif isinstance(obj, errors.InvalidOS):
-    return False
-  else:
-    raise errors.ProgrammerError('unknown OS diagnose type')
-
-
-def _DiagnoseOSName(obj):
-  """Generate a status message for an OS diagnose object.
-
-    Args:
-      obj: an diagnostic object as returned by OpDiagnoseOS
-
-    Returns:
-      string: the name of the OS in question
-  """
-
-  if _DiagnoseOSValid(obj):
-    return obj.name
-  else:
-    return obj.args[0]
-
-
-def _DiagnoseOSStatus(obj):
-  """Generate a status message for an OS diagnose object.
-
-    Args:
-      obj: an diagnostic object as returned by OpDiagnoseOS
-
-    Returns:
-      string: a description of the OS status
-  """
-
-  if _DiagnoseOSValid(obj):
-    return "valid (path: %s)" % obj.path
-  else:
-    return "%s (path: %s)" % (obj.args[2], obj.args[1])
-
-
-def _DiagnoseByOS(rlist):
-  """Remap an OpDiagnoseOS() return list into an a per-os per-node dictionary
-
-    Args:
-      rlist: a map with nodes as keys and diagnoseobjects as values
-
-    Returns:
-      map: a map with osnames as keys and as value another map, with nodes as
-           keys and diagnoseobjects as values
-           e.g. {"debian-etch": {"node1": <object>, "node2": <object>}}
-  """
-
-  all_os = {}
-  for node_name, nr in rlist.iteritems():
-    if not nr:
-      continue
-    for obj in nr:
-      os_name = _DiagnoseOSName(obj)
-      if os_name not in all_os:
-        all_os[os_name] = {}
-      if node_name not in all_os[os_name]:
-        all_os[os_name][node_name] = []
-      all_os[os_name][node_name].append(obj)
-
-  return all_os
+from ganeti import constants
 
 
 def ListOS(opts, args):
   """List the OSes existing on this node.
 
   """
-  op = opcodes.OpDiagnoseOS()
+  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid"], names=[])
   result = SubmitOpCode(op)
 
   if not result:
     logger.ToStdout("Can't get the OS list")
     return 1
 
-  node_data = result
-  num_nodes = len(node_data)
-  all_os = _DiagnoseByOS(node_data)
-
-  valid_os = []
-  for os_name, os_node_data in all_os.iteritems():
-    if len(os_node_data) != num_nodes:
-      continue
-    valid = True
-    for l in os_node_data.values():
-      if not _DiagnoseOSValid(l[0]):
-        valid = False
-        break
-    if valid:
-      valid_os.append(os_name)
-
   if not opts.no_headers:
     headers = {"name": "Name"}
   else:
     headers = None
 
   data = GenerateTable(separator=None, headers=headers, fields=["name"],
-                       data=[[os] for os in valid_os])
+                       data=[[row[0]] for row in result if row[1]])
 
   for line in data:
     logger.ToStdout(line)
@@ -152,41 +60,33 @@ def DiagnoseOS(opts, args):
   """Analyse all OSes on this cluster.
 
   """
-  op = opcodes.OpDiagnoseOS()
+  op = opcodes.OpDiagnoseOS(output_fields=["name", "valid", "node_status"],
+                            names=[])
   result = SubmitOpCode(op)
 
   if not result:
     logger.ToStdout("Can't get the OS list")
     return 1
 
-  node_data = result
-  all_os = _DiagnoseByOS(node_data)
-
-  format = "%-*s %-*s %s"
-
-  max_name = len('Name')
-  if all_os:
-    max_name = max(max_name, max([len(name) for name in all_os]))
-
-  max_node = len('Status/Node')
-  max_node = max(max_node, max([len(name) for name in node_data]))
-
-  logger.ToStdout(format % (max_name, 'Name', max_node, 'Status/Node',
-                            'Details'))
-
   has_bad = False
 
-  for os_name in all_os:
+  for os_name, os_valid, node_data in result:
     nodes_valid = {}
     nodes_bad = {}
-    for node_name in node_data:
-      if node_name in all_os[os_name]:
-        first_os = all_os[os_name][node_name].pop(0)
-        first_os_status = _DiagnoseOSStatus(first_os)
-        if _DiagnoseOSValid(first_os):
-          nodes_valid[node_name] = first_os_status
+    nodes_hidden = {}
+    for node_name, node_info in node_data.iteritems():
+      nodes_hidden[node_name] = []
+      if node_info: # at least one entry in the per-node list
+        first_os_status, first_os_path = node_info.pop(0)
+        first_os_msg = ("%s (path: %s)" %
+                        (first_os_status, first_os_path))
+        if first_os_status == constants.OS_VALID_STATUS:
+          nodes_valid[node_name] = first_os_msg
         else:
-          nodes_bad[node_name] = first_os_status
+          nodes_bad[node_name] = first_os_msg
+        for hstatus, hpath in node_info:
+          nodes_hidden[node_name].append("    [hidden] path: %s, status: %s" %
+                                         (hpath, hstatus))
       else:
         nodes_bad[node_name] = "OS not found"
 
@@ -199,23 +99,18 @@ def DiagnoseOS(opts, args):
       status = "partial valid"
       has_bad = True
 
-    def _OutputNodeHiddenOSStatus(dobj_list):
-      for dobj in dobj_list:
-        logger.ToStdout(format % (max_name, "", max_node, "",
-                                  "[hidden] %s" %
-                                  _DiagnoseOSStatus(dobj)))
-
-    def _OutputPerNodeOSStatus(status_map):
-      map_k = utils.NiceSort(status_map.keys())
+    def _OutputPerNodeOSStatus(msg_map):
+      map_k = utils.NiceSort(msg_map.keys())
       for node_name in map_k:
-        logger.ToStdout(format % (max_name, "", max_node,
-                                  node_name, status_map[node_name]))
-        if node_name in all_os[os_name]:
-          _OutputNodeHiddenOSStatus(all_os[os_name][node_name])
+        logger.ToStdout("  Node: %s, status: %s" %
+                        (node_name, msg_map[node_name]))
+        for msg in nodes_hidden[node_name]:
+          logger.ToStdout(msg)
 
-    logger.ToStdout(format % (max_name, os_name, max_node, status, ""))
+    logger.ToStdout("OS: %s [global status: %s]" % (os_name, status))
     _OutputPerNodeOSStatus(nodes_valid)
     _OutputPerNodeOSStatus(nodes_bad)
+    logger.ToStdout("")
 
   return int(has_bad)