From e8a4c13875773e9bc204f535aec3c92b74b20ccf Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Mon, 5 May 2008 10:01:39 +0000
Subject: [PATCH] Add node cpu count to gnt-node list

This patch adds the backend and frontend changes needed for being able
to list the cpu count.

Reviewed-by: ultrotter
---
 lib/cmdlib.py                    | 10 +++++++---
 lib/constants.py                 |  2 +-
 lib/hypervisor/FakeHypervisor.py | 15 ++++++++++++++-
 lib/hypervisor/XenHypervisor.py  |  2 ++
 scripts/gnt-node                 | 21 +++++++++++++--------
 5 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index fef04f651..f73a976ce 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1492,9 +1492,12 @@ class LUQueryNodes(NoHooksLU):
     This checks that the fields required are valid output fields.
 
     """
-    self.dynamic_fields = frozenset(["dtotal", "dfree",
-                                     "mtotal", "mnode", "mfree",
-                                     "bootid"])
+    self.dynamic_fields = frozenset([
+      "dtotal", "dfree",
+      "mtotal", "mnode", "mfree",
+      "bootid",
+      "ctotal",
+      ])
 
     _CheckOutputFields(static=["name", "pinst_cnt", "sinst_cnt",
                                "pinst_list", "sinst_list",
@@ -1525,6 +1528,7 @@ class LUQueryNodes(NoHooksLU):
             "mfree": utils.TryConvert(int, nodeinfo['memory_free']),
             "dtotal": utils.TryConvert(int, nodeinfo['vg_size']),
             "dfree": utils.TryConvert(int, nodeinfo['vg_free']),
+            "ctotal": utils.TryConvert(int, nodeinfo['cpu_total']),
             "bootid": nodeinfo['bootid'],
             }
         else:
diff --git a/lib/constants.py b/lib/constants.py
index 896fc4803..907f61712 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -25,7 +25,7 @@ from ganeti import _autoconf
 
 # various versions
 CONFIG_VERSION = 3
-PROTOCOL_VERSION = 11
+PROTOCOL_VERSION = 12
 RELEASE_VERSION = _autoconf.PACKAGE_VERSION
 OS_API_VERSION = 5
 EXPORT_VERSION = 0
diff --git a/lib/hypervisor/FakeHypervisor.py b/lib/hypervisor/FakeHypervisor.py
index 02687bd57..debfeaaf6 100644
--- a/lib/hypervisor/FakeHypervisor.py
+++ b/lib/hypervisor/FakeHypervisor.py
@@ -25,6 +25,7 @@
 
 import os
 import os.path
+import re
 
 from ganeti import utils
 from ganeti import constants
@@ -186,8 +187,20 @@ class FakeHypervisor(BaseHypervisor.BaseHypervisor):
           sum_free += int(val.split()[0])/1024
         elif key == 'Active':
           result['memory_dom0'] = int(val.split()[0])/1024
-
     result['memory_free'] = sum_free
+
+    cpu_total = 0
+    try:
+      fh = open("/proc/cpuinfo")
+      try:
+        cpu_total = len(re.findall("(?m)^processor\s*:\s*[0-9]+\s*$",
+                                   fh.read()))
+      finally:
+        fh.close()
+    except EnvironmentError, err:
+      raise HypervisorError("Failed to list node info: %s" % err)
+    result['cpu_total'] = cpu_total
+
     return result
 
   @staticmethod
diff --git a/lib/hypervisor/XenHypervisor.py b/lib/hypervisor/XenHypervisor.py
index cddf731a1..deccd6290 100644
--- a/lib/hypervisor/XenHypervisor.py
+++ b/lib/hypervisor/XenHypervisor.py
@@ -199,6 +199,8 @@ class XenHypervisor(BaseHypervisor.BaseHypervisor):
           result['memory_total'] = int(val)
         elif key == 'free_memory':
           result['memory_free'] = int(val)
+        elif key == 'nr_cpus':
+          result['cpu_total'] = int(val)
     dom0_info = self.GetInstanceInfo("Domain-0")
     if dom0_info is not None:
       result['memory_dom0'] = dom0_info[2]
diff --git a/scripts/gnt-node b/scripts/gnt-node
index c8082c901..bd31a1333 100755
--- a/scripts/gnt-node
+++ b/scripts/gnt-node
@@ -56,12 +56,15 @@ def ListNodes(opts, args):
   output = SubmitOpCode(op)
 
   if not opts.no_headers:
-    headers = {"name": "Node", "pinst_cnt": "Pinst", "sinst_cnt": "Sinst",
-               "pinst_list": "PriInstances", "sinst_list": "SecInstances",
-               "pip": "PrimaryIP", "sip": "SecondaryIP",
-               "dtotal": "DTotal", "dfree": "DFree",
-               "mtotal": "MTotal", "mnode": "MNode", "mfree": "MFree",
-               "bootid": "BootID"}
+    headers = {
+      "name": "Node", "pinst_cnt": "Pinst", "sinst_cnt": "Sinst",
+      "pinst_list": "PriInstances", "sinst_list": "SecInstances",
+      "pip": "PrimaryIP", "sip": "SecondaryIP",
+      "dtotal": "DTotal", "dfree": "DFree",
+      "mtotal": "MTotal", "mnode": "MNode", "mfree": "MFree",
+      "bootid": "BootID",
+      "ctotal": "CTotal",
+      }
   else:
     headers = None
 
@@ -72,7 +75,8 @@ def ListNodes(opts, args):
 
   numfields = ["dtotal", "dfree",
                "mtotal", "mnode", "mfree",
-               "pinst_cnt", "sinst_cnt"]
+               "pinst_cnt", "sinst_cnt",
+               "ctotal"]
 
   # change raw values to nicer strings
   for row in output:
@@ -309,7 +313,8 @@ commands = {
            "", "Lists the nodes in the cluster. The available fields"
            " are (see the man page for details): name, pinst_cnt, pinst_list,"
            " sinst_cnt, sinst_list, pip, sip, dtotal, dfree, mtotal, mnode,"
-           " mfree, bootid. The default field list is (in order): name,"
+           " mfree, bootid, cpu_count. The default field list is"
+           " (in order): name,"
            " dtotal, dfree, mtotal, mnode, mfree, pinst_cnt, sinst_cnt."),
   'remove': (RemoveNode, ARGS_ONE, [DEBUG_OPT],
              "<node_name>", "Removes a node from the cluster"),
-- 
GitLab