Revision 32389d91
b/lib/backend.py | ||
---|---|---|
589 | 589 |
return { |
590 | 590 |
"type": constants.ST_LVM_VG, |
591 | 591 |
"name": name, |
592 |
"vg_free": vg_free,
|
|
593 |
"vg_size": vg_size,
|
|
592 |
"storage_free": vg_free,
|
|
593 |
"storage_size": vg_size,
|
|
594 | 594 |
} |
595 | 595 |
|
596 | 596 |
|
... | ... | |
614 | 614 |
return { |
615 | 615 |
"type": constants.ST_LVM_PV, |
616 | 616 |
"name": name, |
617 |
"vg_free": vg_free,
|
|
618 |
"vg_size": vg_size,
|
|
617 |
"storage_free": vg_free,
|
|
618 |
"storage_size": vg_size,
|
|
619 | 619 |
} |
620 | 620 |
|
621 | 621 |
|
b/lib/cmdlib/instance_storage.py | ||
---|---|---|
893 | 893 |
|
894 | 894 |
""" |
895 | 895 |
es_flags = rpc.GetExclusiveStorageForNodes(lu.cfg, node_uuids) |
896 |
# FIXME: This maps everything to storage type 'lvm-vg' to maintain |
|
897 |
# the current functionality. Refactor to make it more flexible. |
|
898 | 896 |
hvname = lu.cfg.GetHypervisorType() |
899 | 897 |
hvparams = lu.cfg.GetClusterInfo().hvparams |
900 | 898 |
nodeinfo = lu.rpc.call_node_info(node_uuids, [(constants.ST_LVM_VG, vg)], |
... | ... | |
906 | 904 |
info.Raise("Cannot get current information from node %s" % node_name, |
907 | 905 |
prereq=True, ecode=errors.ECODE_ENVIRON) |
908 | 906 |
(_, (vg_info, ), _) = info.payload |
909 |
vg_free = vg_info.get("vg_free", None)
|
|
907 |
vg_free = vg_info.get("storage_free", None)
|
|
910 | 908 |
if not isinstance(vg_free, int): |
911 | 909 |
raise errors.OpPrereqError("Can't compute free disk space on node" |
912 | 910 |
" %s for vg %s, result was '%s'" % |
b/lib/cmdlib/node.py | ||
---|---|---|
1184 | 1184 |
es_flags = rpc.GetExclusiveStorageForNodes(lu.cfg, toquery_node_uuids) |
1185 | 1185 |
# FIXME: This currently maps everything to lvm, this should be more |
1186 | 1186 |
# flexible |
1187 |
vg_req = rpc.BuildVgInfoQuery(lu.cfg) |
|
1187 |
lvm_enabled = utils.storage.IsLvmEnabled( |
|
1188 |
lu.cfg.GetClusterInfo().enabled_disk_templates) |
|
1189 |
storage_units = utils.storage.GetStorageUnitsOfCluster( |
|
1190 |
lu.cfg, include_spindles=True) |
|
1188 | 1191 |
default_hypervisor = lu.cfg.GetHypervisorType() |
1189 | 1192 |
hvparams = lu.cfg.GetClusterInfo().hvparams[default_hypervisor] |
1190 | 1193 |
hvspecs = [(default_hypervisor, hvparams)] |
1191 |
node_data = lu.rpc.call_node_info(toquery_node_uuids, vg_req,
|
|
1194 |
node_data = lu.rpc.call_node_info(toquery_node_uuids, storage_units,
|
|
1192 | 1195 |
hvspecs, es_flags) |
1193 |
live_data = dict((uuid, rpc.MakeLegacyNodeInfo(nresult.payload)) |
|
1194 |
for (uuid, nresult) in node_data.items() |
|
1195 |
if not nresult.fail_msg and nresult.payload) |
|
1196 |
live_data = dict( |
|
1197 |
(uuid, rpc.MakeLegacyNodeInfo(nresult.payload, |
|
1198 |
require_vg_info=lvm_enabled)) |
|
1199 |
for (uuid, nresult) in node_data.items() |
|
1200 |
if not nresult.fail_msg and nresult.payload) |
|
1196 | 1201 |
else: |
1197 | 1202 |
live_data = None |
1198 | 1203 |
|
b/lib/masterd/iallocator.py | ||
---|---|---|
431 | 431 |
node_whitelist = None |
432 | 432 |
|
433 | 433 |
es_flags = rpc.GetExclusiveStorageForNodes(self.cfg, node_list) |
434 |
vg_req = rpc.BuildVgInfoQuery(self.cfg) |
|
435 |
has_lvm = bool(vg_req) |
|
434 |
storage_units = utils.storage.GetStorageUnitsOfCluster( |
|
435 |
self.cfg, include_spindles=True) |
|
436 |
has_lvm = utils.storage.IsLvmEnabled(cluster_info.enabled_disk_templates) |
|
436 | 437 |
hvspecs = [(hypervisor_name, cluster_info.hvparams[hypervisor_name])] |
437 |
node_data = self.rpc.call_node_info(node_list, vg_req,
|
|
438 |
node_data = self.rpc.call_node_info(node_list, storage_units,
|
|
438 | 439 |
hvspecs, es_flags) |
439 | 440 |
node_iinfo = \ |
440 | 441 |
self.rpc.call_all_instances_info(node_list, |
... | ... | |
551 | 552 |
|
552 | 553 |
# TODO: replace this with proper storage reporting |
553 | 554 |
if has_lvm: |
554 |
total_disk = get_attr("vg_size")
|
|
555 |
free_disk = get_attr("vg_free")
|
|
555 |
total_disk = get_attr("storage_size")
|
|
556 |
free_disk = get_attr("storage_free")
|
|
556 | 557 |
total_spindles = get_attr("spindles_total") |
557 | 558 |
free_spindles = get_attr("spindles_free") |
558 | 559 |
else: |
b/lib/query.py | ||
---|---|---|
1155 | 1155 |
"csockets": ("CSockets", QFT_NUMBER, "cpu_sockets", |
1156 | 1156 |
"Number of physical CPU sockets (if exported by hypervisor)"), |
1157 | 1157 |
"ctotal": ("CTotal", QFT_NUMBER, "cpu_total", "Number of logical processors"), |
1158 |
"dfree": ("DFree", QFT_UNIT, "vg_free",
|
|
1159 |
"Available disk space in volume group"),
|
|
1160 |
"dtotal": ("DTotal", QFT_UNIT, "vg_size",
|
|
1161 |
"Total disk space in volume group used for instance disk"
|
|
1158 |
"dfree": ("DFree", QFT_UNIT, "storage_free",
|
|
1159 |
"Available storage space in storage unit"),
|
|
1160 |
"dtotal": ("DTotal", QFT_UNIT, "storage_size",
|
|
1161 |
"Total storage space in storage unit used for instance disk"
|
|
1162 | 1162 |
" allocation"), |
1163 | 1163 |
"spfree": ("SpFree", QFT_NUMBER, "spindles_free", |
1164 | 1164 |
"Available spindles in volume group (exclusive storage only)"), |
b/lib/rpc.py | ||
---|---|---|
592 | 592 |
return [(d.ToDict(), uid) for d, uid in value] |
593 | 593 |
|
594 | 594 |
|
595 |
def BuildVgInfoQuery(cfg): |
|
596 |
"""Build a query about the default VG for C{node_info}. |
|
595 |
def _AddSpindlesToLegacyNodeInfo(result, space_info): |
|
596 |
"""Extracts the spindle information from the space info and adds |
|
597 |
it to the result dictionary. |
|
598 |
|
|
599 |
@type result: dict of strings |
|
600 |
@param result: dictionary holding the result of the legacy node info |
|
601 |
@type space_info: list of dicts of strings |
|
602 |
@param space_info: list, each row holding space information of one storage |
|
603 |
unit |
|
604 |
@rtype: None |
|
605 |
@return: does not return anything, manipulates the C{result} variable |
|
597 | 606 |
|
598 |
The result of the RPC can be parsed with L{MakeLegacyNodeInfo}. |
|
607 |
""" |
|
608 |
lvm_pv_info = utils.storage.LookupSpaceInfoByStorageType( |
|
609 |
space_info, constants.ST_LVM_PV) |
|
610 |
if lvm_pv_info: |
|
611 |
result["spindles_free"] = lvm_pv_info["storage_free"] |
|
612 |
result["spindles_total"] = lvm_pv_info["storage_size"] |
|
599 | 613 |
|
600 |
@type cfg: L{config.ConfigWriter} |
|
601 |
@param cfg: Cluster configuration |
|
602 |
@rtype: list |
|
603 |
@return: argument suitable for L{rpc.RpcRunner.call_node_info} |
|
614 |
|
|
615 |
def _AddDefaultStorageInfoToLegacyNodeInfo(result, space_info, |
|
616 |
require_vg_info=True): |
|
617 |
"""Extracts the storage space information of the default storage type from |
|
618 |
the space info and adds it to the result dictionary. |
|
619 |
|
|
620 |
@see: C{_AddSpindlesToLegacyNodeInfo} for parameter information. |
|
621 |
@type require_vg_info: boolean |
|
622 |
@param require_vg_info: indicates whether volume group information is |
|
623 |
required or not |
|
604 | 624 |
|
605 | 625 |
""" |
606 |
vg_name = cfg.GetVGName() |
|
607 |
if vg_name: |
|
608 |
ret = [ |
|
609 |
(constants.ST_LVM_VG, vg_name), |
|
610 |
(constants.ST_LVM_PV, vg_name), |
|
611 |
] |
|
626 |
# Check if there is at least one row for non-spindle storage info. |
|
627 |
no_defaults = (len(space_info) < 1) or \ |
|
628 |
(space_info[0]["type"] == constants.ST_LVM_PV and len(space_info) == 1) |
|
629 |
|
|
630 |
default_space_info = None |
|
631 |
if no_defaults: |
|
632 |
logging.warning("No storage info provided for default storage type.") |
|
612 | 633 |
else: |
613 |
ret = [] |
|
614 |
return ret |
|
634 |
default_space_info = space_info[0] |
|
635 |
|
|
636 |
if require_vg_info: |
|
637 |
if no_defaults or not default_space_info["type"] == constants.ST_LVM_VG: |
|
638 |
raise errors.OpExecError("LVM volume group info required, but not" |
|
639 |
" provided.") |
|
640 |
|
|
641 |
if default_space_info: |
|
642 |
result["name"] = default_space_info["name"] |
|
643 |
result["storage_free"] = default_space_info["storage_free"] |
|
644 |
result["storage_size"] = default_space_info["storage_size"] |
|
615 | 645 |
|
616 | 646 |
|
617 | 647 |
def MakeLegacyNodeInfo(data, require_vg_info=True): |
... | ... | |
624 | 654 |
doesn't have any values |
625 | 655 |
|
626 | 656 |
""" |
627 |
(bootid, vgs_info, (hv_info, )) = data
|
|
657 |
(bootid, space_info, (hv_info, )) = data
|
|
628 | 658 |
|
629 | 659 |
ret = utils.JoinDisjointDicts(hv_info, {"bootid": bootid}) |
630 | 660 |
|
631 |
if require_vg_info or vgs_info: |
|
632 |
(vg0_info, vg0_spindles) = vgs_info |
|
633 |
ret = utils.JoinDisjointDicts(vg0_info, ret) |
|
634 |
ret["spindles_free"] = vg0_spindles["vg_free"] |
|
635 |
ret["spindles_total"] = vg0_spindles["vg_size"] |
|
661 |
_AddSpindlesToLegacyNodeInfo(ret, space_info) |
|
662 |
_AddDefaultStorageInfoToLegacyNodeInfo(ret, space_info, |
|
663 |
require_vg_info=require_vg_info) |
|
636 | 664 |
|
637 | 665 |
return ret |
638 | 666 |
|
b/lib/storage/filestorage.py | ||
---|---|---|
45 | 45 |
size = (result.f_frsize * result.f_blocks) / (1024 * 1024) |
46 | 46 |
return {"type": constants.ST_FILE, |
47 | 47 |
"name": path, |
48 |
"vg_size": size,
|
|
49 |
"vg_free": free}
|
|
48 |
"storage_size": size,
|
|
49 |
"storage_free": free}
|
|
50 | 50 |
except OSError, e: |
51 | 51 |
raise errors.CommandError("Failed to retrieve file system information about" |
52 | 52 |
" path: %s - %s" % (path, e.strerror)) |
b/src/Ganeti/Query/Node.hs | ||
---|---|---|
61 | 61 |
"Number of physical CPU sockets (if exported by hypervisor)") |
62 | 62 |
, ("ctotal", "CTotal", QFTNumber, "cpu_total", |
63 | 63 |
"Number of logical processors") |
64 |
, ("dfree", "DFree", QFTUnit, "vg_free",
|
|
65 |
"Available disk space in volume group")
|
|
66 |
, ("dtotal", "DTotal", QFTUnit, "vg_size",
|
|
67 |
"Total disk space in volume group used for instance disk allocation")
|
|
64 |
, ("dfree", "DFree", QFTUnit, "storage_free",
|
|
65 |
"Available storage space on storage unit")
|
|
66 |
, ("dtotal", "DTotal", QFTUnit, "storage_size",
|
|
67 |
"Total storage space on storage unit for instance disk allocation")
|
|
68 | 68 |
, ("spfree", "SpFree", QFTNumber, "spindles_free", |
69 | 69 |
"Available spindles in volume group (exclusive storage only)") |
70 | 70 |
, ("sptotal", "SpTotal", QFTNumber, "spindles_total", |
... | ... | |
89 | 89 |
nodeLiveFieldExtract "ctotal" res = |
90 | 90 |
jsonHead (rpcResNodeInfoHvInfo res) hvInfoCpuTotal |
91 | 91 |
nodeLiveFieldExtract "dfree" res = |
92 |
getMaybeJsonHead (rpcResNodeInfoVgInfo res) vgInfoVgFree
|
|
92 |
getMaybeJsonHead (rpcResNodeInfoStorageInfo res) storageInfoStorageFree
|
|
93 | 93 |
nodeLiveFieldExtract "dtotal" res = |
94 |
getMaybeJsonHead (rpcResNodeInfoVgInfo res) vgInfoVgSize
|
|
94 |
getMaybeJsonHead (rpcResNodeInfoStorageInfo res) storageInfoStorageSize
|
|
95 | 95 |
nodeLiveFieldExtract "spfree" res = |
96 |
getMaybeJsonElem (rpcResNodeInfoVgInfo res) 1 vgInfoVgFree
|
|
96 |
getMaybeJsonElem (rpcResNodeInfoStorageInfo res) 1 storageInfoStorageFree
|
|
97 | 97 |
nodeLiveFieldExtract "sptotal" res = |
98 |
getMaybeJsonElem (rpcResNodeInfoVgInfo res) 1 vgInfoVgSize
|
|
98 |
getMaybeJsonElem (rpcResNodeInfoStorageInfo res) 1 storageInfoStorageSize
|
|
99 | 99 |
nodeLiveFieldExtract "mfree" res = |
100 | 100 |
jsonHead (rpcResNodeInfoHvInfo res) hvInfoMemoryFree |
101 | 101 |
nodeLiveFieldExtract "mnode" res = |
b/src/Ganeti/Rpc.hs | ||
---|---|---|
52 | 52 |
, RpcResultInstanceList(..) |
53 | 53 |
|
54 | 54 |
, HvInfo(..) |
55 |
, VgInfo(..)
|
|
55 |
, StorageInfo(..)
|
|
56 | 56 |
, RpcCallNodeInfo(..) |
57 | 57 |
, RpcResultNodeInfo(..) |
58 | 58 |
|
... | ... | |
342 | 342 |
, simpleField "exclusive_storage" [t| Map.Map String Bool |] |
343 | 343 |
]) |
344 | 344 |
|
345 |
$(buildObject "VgInfo" "vgInfo"
|
|
345 |
$(buildObject "StorageInfo" "storageInfo"
|
|
346 | 346 |
[ simpleField "name" [t| String |] |
347 | 347 |
, simpleField "type" [t| String |] |
348 |
, optionalField $ simpleField "vg_free" [t| Int |]
|
|
349 |
, optionalField $ simpleField "vg_size" [t| Int |]
|
|
348 |
, optionalField $ simpleField "storage_free" [t| Int |]
|
|
349 |
, optionalField $ simpleField "storage_size" [t| Int |]
|
|
350 | 350 |
]) |
351 | 351 |
|
352 | 352 |
-- | We only provide common fields as described in hv_base.py. |
... | ... | |
361 | 361 |
|
362 | 362 |
$(buildObject "RpcResultNodeInfo" "rpcResNodeInfo" |
363 | 363 |
[ simpleField "boot_id" [t| String |] |
364 |
, simpleField "vg_info" [t| [VgInfo] |]
|
|
364 |
, simpleField "storage_info" [t| [StorageInfo] |]
|
|
365 | 365 |
, simpleField "hv_info" [t| [HvInfo] |] |
366 | 366 |
]) |
367 | 367 |
|
b/test/py/ganeti.rpc_unittest.py | ||
---|---|---|
900 | 900 |
class TestLegacyNodeInfo(unittest.TestCase): |
901 | 901 |
KEY_BOOT = "bootid" |
902 | 902 |
KEY_VG0 = "name" |
903 |
KEY_VG1 = "vg_free"
|
|
904 |
KEY_VG2 = "vg_size"
|
|
903 |
KEY_VG1 = "storage_free"
|
|
904 |
KEY_VG2 = "storage_size"
|
|
905 | 905 |
KEY_HV = "cpu_count" |
906 | 906 |
KEY_SP1 = "spindles_free" |
907 | 907 |
KEY_SP2 = "spindles_total" |
908 |
KEY_ST = "type" # key for storage type |
|
908 | 909 |
VAL_BOOT = 0 |
909 | 910 |
VAL_VG0 = "xy" |
910 | 911 |
VAL_VG1 = 11 |
911 | 912 |
VAL_VG2 = 12 |
913 |
VAL_VG3 = "lvm-vg" |
|
912 | 914 |
VAL_HV = 2 |
913 | 915 |
VAL_SP0 = "ab" |
914 | 916 |
VAL_SP1 = 31 |
915 | 917 |
VAL_SP2 = 32 |
918 |
VAL_SP3 = "lvm-pv" |
|
916 | 919 |
DICT_VG = { |
917 | 920 |
KEY_VG0: VAL_VG0, |
918 | 921 |
KEY_VG1: VAL_VG1, |
919 | 922 |
KEY_VG2: VAL_VG2, |
923 |
KEY_ST: VAL_VG3, |
|
920 | 924 |
} |
921 | 925 |
DICT_HV = {KEY_HV: VAL_HV} |
922 | 926 |
DICT_SP = { |
927 |
KEY_ST: VAL_SP3, |
|
923 | 928 |
KEY_VG0: VAL_SP0, |
924 | 929 |
KEY_VG1: VAL_SP1, |
925 | 930 |
KEY_VG2: VAL_SP2, |
... | ... | |
941 | 946 |
|
942 | 947 |
def testReqVg(self): |
943 | 948 |
my_lst = [self.VAL_BOOT, [], [self.DICT_HV]] |
944 |
self.assertRaises(ValueError, rpc.MakeLegacyNodeInfo, my_lst)
|
|
949 |
self.assertRaises(errors.OpExecError, rpc.MakeLegacyNodeInfo, my_lst)
|
|
945 | 950 |
|
946 | 951 |
def testNoReqVg(self): |
947 | 952 |
my_lst = [self.VAL_BOOT, [], [self.DICT_HV]] |
Also available in: Unified diff