From 71c1af5860c74a6de4900faae728dc6320a1042c Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Tue, 18 Nov 2008 10:06:01 +0000
Subject: [PATCH] Allow querying of variable number of parameters

This patch adds support for querying in gnt-instance list of:
  - disk.count
  - nic.count
  - disk.size/$N
  - nic.(ip|mac|bridge)/$N

The patch also disables the exception raised when the header description
is missing, that should be fixed in the future (together with better
handling of variable numeric fields).

Reviewed-by: imsnah
---
 lib/cli.py    |  6 ++++--
 lib/cmdlib.py | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/lib/cli.py b/lib/cli.py
index b95b6ae07..d19ca986e 100644
--- a/lib/cli.py
+++ b/lib/cli.py
@@ -755,8 +755,10 @@ def GenerateTable(headers, fields, separator, data,
   format_fields = []
   for field in fields:
     if headers and field not in headers:
-      raise errors.ProgrammerError("Missing header description for field '%s'"
-                                   % field)
+      # FIXME: handle better unknown fields (either revert to old
+      # style of raising exception, or deal more intelligently with
+      # variable fields)
+      headers[field] = field
     if separator is not None:
       format_fields.append("%s")
     elif field in numfields:
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 289e4c8b9..ee7af81ea 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -2719,6 +2719,9 @@ class LUQueryInstances(NoHooksLU):
                                "disk_template", "ip", "mac", "bridge",
                                "sda_size", "sdb_size", "vcpus", "tags",
                                "network_port", "beparams",
+                               "(disk).(size)/([0-9]+)",
+                               "(nic).(mac|ip|bridge)/([0-9]+)",
+                               "(disk|nic).(count)",
                                "serial_no", "hypervisor", "hvparams",] +
                              ["hv/%s" % name
                               for name in constants.HVS_PARAMETERS] +
@@ -2806,6 +2809,7 @@ class LUQueryInstances(NoHooksLU):
       i_hv = self.cfg.GetClusterInfo().FillHV(instance)
       i_be = self.cfg.GetClusterInfo().FillBE(instance)
       for field in self.op.output_fields:
+        st_match = self._FIELDS_STATIC.Matches(field)
         if field == "name":
           val = instance.name
         elif field == "os":
@@ -2875,6 +2879,39 @@ class LUQueryInstances(NoHooksLU):
         elif (field.startswith(BEPREFIX) and
               field[len(BEPREFIX):] in constants.BES_PARAMETERS):
           val = i_be.get(field[len(BEPREFIX):], None)
+        elif st_match and st_match.groups():
+          # matches a variable list
+          st_groups = st_match.groups()
+          if st_groups and st_groups[0] == "disk":
+            if st_groups[1] == "count":
+              val = len(instance.disks)
+            elif st_groups[1] == "size":
+              disk_idx = int(st_groups[2])
+              if disk_idx >= len(instance.disks):
+                val = None
+              else:
+                val = instance.disks[disk_idx].size
+            else:
+              assert False, "Unhandled disk parameter"
+          elif st_groups[0] == "nic":
+            if st_groups[1] == "count":
+              val = len(instance.nics)
+            else:
+              # index-based item
+              nic_idx = int(st_groups[2])
+              if nic_idx >= len(instance.nics):
+                val = None
+              else:
+                if st_groups[1] == "mac":
+                  val = instance.nics[nic_idx].mac
+                elif st_groups[1] == "ip":
+                  val = instance.nics[nic_idx].ip
+                elif st_groups[1] == "bridge":
+                  val = instance.nics[nic_idx].bridge
+                else:
+                  assert False, "Unhandled NIC parameter"
+          else:
+            assert False, "Unhandled variable parameter"
         else:
           raise errors.ParameterError(field)
         iout.append(val)
-- 
GitLab