Revision 4f90370c
b/NEWS | ||
---|---|---|
19 | 19 |
when allocating space for a file/sharedfile instance. |
20 | 20 |
- When disabling disk templates cluster-wide, the cluster now first |
21 | 21 |
checks whether there are instances still using those templates. |
22 |
- 'gnt-node list-storage' now also reports storage information about |
|
23 |
file-based storage types. |
|
22 | 24 |
|
23 | 25 |
New features |
24 | 26 |
~~~~~~~~~~~~ |
b/lib/client/gnt_node.py | ||
---|---|---|
817 | 817 |
@return: the desired exit code |
818 | 818 |
|
819 | 819 |
""" |
820 |
# TODO: Default to ST_FILE if LVM is disabled on the cluster |
|
821 |
if opts.user_storage_type is None: |
|
822 |
opts.user_storage_type = constants.ST_LVM_PV |
|
823 |
|
|
824 |
storage_type = ConvertStorageType(opts.user_storage_type) |
|
825 |
|
|
826 | 820 |
selected_fields = ParseFields(opts.output, _LIST_STOR_DEF_FIELDS) |
827 | 821 |
|
828 | 822 |
op = opcodes.OpNodeQueryStorage(nodes=args, |
829 |
storage_type=storage_type, |
|
823 |
storage_type=opts.user_storage_type,
|
|
830 | 824 |
output_fields=selected_fields) |
831 | 825 |
output = SubmitOpCode(op, opts=opts) |
832 | 826 |
|
b/lib/cmdlib/node.py | ||
---|---|---|
1396 | 1396 |
locking.LEVEL_NODE_ALLOC: locking.ALL_SET, |
1397 | 1397 |
} |
1398 | 1398 |
|
1399 |
def _DetermineStorageType(self): |
|
1400 |
"""Determines the default storage type of the cluster. |
|
1401 |
|
|
1402 |
""" |
|
1403 |
enabled_disk_templates = self.cfg.GetClusterInfo().enabled_disk_templates |
|
1404 |
default_storage_type = \ |
|
1405 |
constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[enabled_disk_templates[0]] |
|
1406 |
return default_storage_type |
|
1407 |
|
|
1399 | 1408 |
def CheckPrereq(self): |
1400 | 1409 |
"""Check prerequisites. |
1401 | 1410 |
|
1402 | 1411 |
""" |
1403 |
CheckStorageTypeEnabled(self.cfg.GetClusterInfo(), self.op.storage_type) |
|
1412 |
if self.op.storage_type: |
|
1413 |
CheckStorageTypeEnabled(self.cfg.GetClusterInfo(), self.op.storage_type) |
|
1414 |
self.storage_type = self.op.storage_type |
|
1415 |
else: |
|
1416 |
self.storage_type = self._DetermineStorageType() |
|
1417 |
if self.storage_type not in constants.STS_REPORT: |
|
1418 |
raise errors.OpPrereqError( |
|
1419 |
"Storage reporting for storage type '%s' is not supported. Please" |
|
1420 |
" use the --storage-type option to specify one of the supported" |
|
1421 |
" storage types (%s) or set the default disk template to one that" |
|
1422 |
" supports storage reporting." % |
|
1423 |
(self.storage_type, utils.CommaJoin(constants.STS_REPORT))) |
|
1404 | 1424 |
|
1405 | 1425 |
def Exec(self, feedback_fn): |
1406 | 1426 |
"""Computes the list of nodes and their attributes. |
1407 | 1427 |
|
1408 | 1428 |
""" |
1429 |
if self.op.storage_type: |
|
1430 |
self.storage_type = self.op.storage_type |
|
1431 |
else: |
|
1432 |
self.storage_type = self._DetermineStorageType() |
|
1433 |
|
|
1409 | 1434 |
self.node_uuids = self.owned_locks(locking.LEVEL_NODE) |
1410 | 1435 |
|
1411 | 1436 |
# Always get name to sort by |
... | ... | |
1422 | 1447 |
field_idx = dict([(name, idx) for (idx, name) in enumerate(fields)]) |
1423 | 1448 |
name_idx = field_idx[constants.SF_NAME] |
1424 | 1449 |
|
1425 |
st_args = _GetStorageTypeArgs(self.cfg, self.op.storage_type)
|
|
1450 |
st_args = _GetStorageTypeArgs(self.cfg, self.storage_type) |
|
1426 | 1451 |
data = self.rpc.call_storage_list(self.node_uuids, |
1427 |
self.op.storage_type, st_args,
|
|
1452 |
self.storage_type, st_args, |
|
1428 | 1453 |
self.op.name, fields) |
1429 | 1454 |
|
1430 | 1455 |
result = [] |
... | ... | |
1452 | 1477 |
if field == constants.SF_NODE: |
1453 | 1478 |
val = node_name |
1454 | 1479 |
elif field == constants.SF_TYPE: |
1455 |
val = self.op.storage_type
|
|
1480 |
val = self.storage_type |
|
1456 | 1481 |
elif field in field_idx: |
1457 | 1482 |
val = row[field_idx[field]] |
1458 | 1483 |
else: |
b/src/Ganeti/OpCodes.hs | ||
---|---|---|
332 | 332 |
[t| [[JSValue]] |], |
333 | 333 |
OpDoc.opNodeQueryStorage, |
334 | 334 |
[ pOutputFields |
335 |
, pStorageType |
|
335 |
, pStorageTypeOptional
|
|
336 | 336 |
, withDoc |
337 | 337 |
"Empty list to query all, list of names to query otherwise" |
338 | 338 |
pNodes |
b/src/Ganeti/OpParams.hs | ||
---|---|---|
150 | 150 |
, pRequiredNodes |
151 | 151 |
, pRequiredNodeUuids |
152 | 152 |
, pStorageType |
153 |
, pStorageTypeOptional |
|
153 | 154 |
, pStorageChanges |
154 | 155 |
, pMasterCandidate |
155 | 156 |
, pOffline |
... | ... | |
834 | 835 |
|
835 | 836 |
pStorageType :: Field |
836 | 837 |
pStorageType = |
837 |
withDoc "Storage type" $ |
|
838 |
simpleField "storage_type" [t| StorageType |] |
|
838 |
withDoc "Storage type" $ simpleField "storage_type" [t| StorageType |] |
|
839 |
|
|
840 |
pStorageTypeOptional :: Field |
|
841 |
pStorageTypeOptional = |
|
842 |
withDoc "Storage type" . |
|
843 |
renameField "StorageTypeOptional" . |
|
844 |
optionalField $ simpleField "storage_type" [t| StorageType |] |
|
839 | 845 |
|
840 | 846 |
pStorageName :: Field |
841 | 847 |
pStorageName = |
b/test/py/ganeti.rapi.rlib2_unittest.py | ||
---|---|---|
630 | 630 |
def testErrors(self): |
631 | 631 |
clfactory = _FakeClientFactory(_FakeClient) |
632 | 632 |
|
633 |
# storage type which does not support space reporting |
|
633 | 634 |
queryargs = { |
634 |
"output_fields": "name,other",
|
|
635 |
"storage_type": constants.ST_DISKLESS,
|
|
635 | 636 |
} |
636 | 637 |
handler = _CreateHandler(rlib2.R_2_nodes_name_storage, |
637 |
["node10538"], queryargs, {}, clfactory)
|
|
638 |
["node21273"], queryargs, {}, clfactory)
|
|
638 | 639 |
self.assertRaises(http.HttpBadRequest, handler.GET) |
639 | 640 |
|
640 | 641 |
queryargs = { |
Also available in: Unified diff