Commit 20faaa74 authored by Helga Velroyen's avatar Helga Velroyen
Browse files

Improve handling of storage info



This patch improves the processing of storage information
as result of the 'node_info' call in the following way:
- It removes the override for LVM storage. This was needed
  in MakeLegacyNode info to be compatible to the
  iallocator, which no longer uses it.
- When no storage information is available (for example
  when only disk templates are enabled, for which no
  storage reporting exists), then this is handled more
  gracefully.
Signed-off-by: default avatarHelga Velroyen <helgav@google.com>
Reviewed-by: default avatarThomas Thrainer <thomasth@google.com>
parent e4f377ae
......@@ -1183,15 +1183,15 @@ class NodeQuery(QueryBase):
# filter out non-vm_capable nodes
toquery_node_uuids = [node.uuid for node in all_info.values()
if node.vm_capable and node.uuid in node_uuids]
lvm_enabled = utils.storage.IsLvmEnabled(
lu.cfg.GetClusterInfo().enabled_disk_templates)
# FIXME: this per default asks for storage space information for all
# enabled disk templates. Fix this by making it possible to specify
# space report fields for specific disk templates.
raw_storage_units = utils.storage.GetStorageUnitsOfCluster(
lu.cfg, include_spindles=True)
lu.cfg, include_spindles=lvm_enabled)
storage_units = rpc.PrepareStorageUnitsForNodes(
lu.cfg, raw_storage_units, toquery_node_uuids)
lvm_enabled = utils.storage.IsLvmEnabled(
lu.cfg.GetClusterInfo().enabled_disk_templates)
default_hypervisor = lu.cfg.GetHypervisorType()
hvparams = lu.cfg.GetClusterInfo().hvparams[default_hypervisor]
hvspecs = [(default_hypervisor, hvparams)]
......@@ -1199,7 +1199,7 @@ class NodeQuery(QueryBase):
hvspecs)
live_data = dict(
(uuid, rpc.MakeLegacyNodeInfo(nresult.payload,
require_vg_info=lvm_enabled))
require_spindles=lvm_enabled))
for (uuid, nresult) in node_data.items()
if not nresult.fail_msg and nresult.payload)
else:
......
......@@ -610,17 +610,15 @@ def _AddSpindlesToLegacyNodeInfo(result, space_info):
if lvm_pv_info:
result["spindles_free"] = lvm_pv_info["storage_free"]
result["spindles_total"] = lvm_pv_info["storage_size"]
else:
raise errors.OpExecError("No spindle storage information available.")
def _AddDefaultStorageInfoToLegacyNodeInfo(result, space_info,
require_vg_info=True):
def _AddDefaultStorageInfoToLegacyNodeInfo(result, space_info):
"""Extracts the storage space information of the default storage type from
the space info and adds it to the result dictionary.
@see: C{_AddSpindlesToLegacyNodeInfo} for parameter information.
@type require_vg_info: boolean
@param require_vg_info: indicates whether volume group information is
required or not
"""
# Check if there is at least one row for non-spindle storage info.
......@@ -633,41 +631,29 @@ def _AddDefaultStorageInfoToLegacyNodeInfo(result, space_info,
else:
default_space_info = space_info[0]
if require_vg_info:
# if lvm storage is required, ignore the actual default and look for LVM
lvm_info_found = False
for space_entry in space_info:
if space_entry["type"] == constants.ST_LVM_VG:
default_space_info = space_entry
lvm_info_found = True
continue
if not lvm_info_found:
raise errors.OpExecError("LVM volume group info required, but not"
" provided.")
if default_space_info:
result["name"] = default_space_info["name"]
result["storage_free"] = default_space_info["storage_free"]
result["storage_size"] = default_space_info["storage_size"]
def MakeLegacyNodeInfo(data, require_vg_info=True):
def MakeLegacyNodeInfo(data, require_spindles=False):
"""Formats the data returned by L{rpc.RpcRunner.call_node_info}.
Converts the data into a single dictionary. This is fine for most use cases,
but some require information from more than one volume group or hypervisor.
@param require_vg_info: raise an error if the returnd vg_info
doesn't have any values
@param require_spindles: add spindle storage information to the legacy node
info
"""
(bootid, space_info, (hv_info, )) = data
ret = utils.JoinDisjointDicts(hv_info, {"bootid": bootid})
_AddSpindlesToLegacyNodeInfo(ret, space_info)
_AddDefaultStorageInfoToLegacyNodeInfo(ret, space_info,
require_vg_info=require_vg_info)
if require_spindles:
_AddSpindlesToLegacyNodeInfo(ret, space_info)
_AddDefaultStorageInfoToLegacyNodeInfo(ret, space_info)
return ret
......
......@@ -936,24 +936,23 @@ class TestLegacyNodeInfo(unittest.TestCase):
KEY_VG1: VAL_VG1,
KEY_VG2: VAL_VG2,
KEY_HV: VAL_HV,
KEY_SP1: VAL_SP1,
KEY_SP2: VAL_SP2,
}
def testStandard(self):
result = rpc.MakeLegacyNodeInfo(self.STD_LST)
self.assertEqual(result, self.STD_DICT)
def testReqVg(self):
def testSpindlesRequired(self):
my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
self.assertRaises(errors.OpExecError, rpc.MakeLegacyNodeInfo, my_lst)
self.assertRaises(errors.OpExecError, rpc.MakeLegacyNodeInfo, my_lst,
require_spindles=True)
def testNoReqVg(self):
def testNoSpindlesRequired(self):
my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
result = rpc.MakeLegacyNodeInfo(my_lst, require_vg_info = False)
result = rpc.MakeLegacyNodeInfo(my_lst, require_spindles = False)
self.assertEqual(result, {self.KEY_BOOT: self.VAL_BOOT,
self.KEY_HV: self.VAL_HV})
result = rpc.MakeLegacyNodeInfo(self.STD_LST, require_vg_info = False)
result = rpc.MakeLegacyNodeInfo(self.STD_LST, require_spindles = False)
self.assertEqual(result, self.STD_DICT)
......@@ -964,48 +963,31 @@ class TestAddDefaultStorageInfoToLegacyNodeInfo(unittest.TestCase):
self.total_storage_file = 42
self.free_storage_lvm = 69
self.total_storage_lvm = 666
self.node_info = [{"name": "mynode",
self.node_info = [{"name": "myfile",
"type": constants.ST_FILE,
"storage_free": self.free_storage_file,
"storage_size": self.total_storage_file},
{"name": "mynode",
{"name": "myvg",
"type": constants.ST_LVM_VG,
"storage_free": self.free_storage_lvm,
"storage_size": self.total_storage_lvm},
{"name": "mynode",
{"name": "myspindle",
"type": constants.ST_LVM_PV,
"storage_free": 33,
"storage_size": 44}]
def testAddDefaultStorageInfoToLegacyNodeInfo(self):
result = {}
has_lvm = False
rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info, has_lvm)
rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info)
self.assertEqual(self.free_storage_file, result["storage_free"])
self.assertEqual(self.total_storage_file, result["storage_size"])
def testAddDefaultStorageInfoToLegacyNodeInfoOverrideDefault(self):
result = {}
has_lvm = True
rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info, has_lvm)
self.assertEqual(self.free_storage_lvm, result["storage_free"])
self.assertEqual(self.total_storage_lvm, result["storage_size"])
def testAddDefaultStorageInfoToLegacyNodeInfoNoDefaults(self):
result = {}
has_lvm = False
rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info[-1:],
has_lvm)
rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info[-1:])
self.assertFalse("storage_free" in result)
self.assertFalse("storage_size" in result)
def testAddDefaultStorageInfoToLegacyNodeInfoNoLvm(self):
result = {}
has_lvm = True
self.assertRaises(errors.OpExecError,
rpc._AddDefaultStorageInfoToLegacyNodeInfo,
result, self.node_info[-1:], has_lvm)
if __name__ == "__main__":
testutils.GanetiTestProgram()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment