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