Commit 5a904197 authored by Santi Raffa's avatar Santi Raffa Committed by Thomas Thrainer

Gluster: add the Shared File storage type

The shared file and gluster disk templates should not report their disk
space information like file does, because they do not behave the same.

If a cluster pulls from the same, shared source of storage then it is
not correct, or useful, to report per-node disk availability, as the
information is not node-specific.

This change introduces the Shared File storage type for which no
per-node measuring of disk resources is made.
Signed-off-by: default avatarSanti Raffa <rsanti@google.com>
Signed-off-by: default avatarThomas Thrainer <thomasth@google.com>
Reviewed-by: default avatarThomas Thrainer <thomasth@google.com>
parent 6488e5bc
......@@ -778,6 +778,7 @@ _STORAGE_TYPE_INFO_FN = {
constants.ST_FILE: _GetFileStorageSpaceInfo,
constants.ST_LVM_PV: _GetLvmPvSpaceInfo,
constants.ST_LVM_VG: _GetLvmVgSpaceInfo,
constants.ST_SHARED_FILE: None,
constants.ST_RADOS: None,
}
......
......@@ -387,13 +387,16 @@ def _PrepareFileBasedStorage(
@param default_dir: default file storage directory when C{file_storage_dir}
is 'None'
@type file_disk_template: string
@param file_disk_template: a disk template whose storage type is 'ST_FILE'
@param file_disk_template: a disk template whose storage type is 'ST_FILE' or
'ST_SHARED_FILE'
@rtype: string
@returns: the name of the actual file storage directory
"""
assert (file_disk_template in
utils.storage.GetDiskTemplatesOfStorageType(constants.ST_FILE))
assert (file_disk_template in utils.storage.GetDiskTemplatesOfStorageTypes(
constants.ST_FILE, constants.ST_SHARED_FILE
))
if file_storage_dir is None:
file_storage_dir = default_dir
if not acceptance_fn:
......
......@@ -89,6 +89,7 @@ _USER_STORAGE_TYPE = {
constants.ST_FILE: "file",
constants.ST_LVM_PV: "lvm-pv",
constants.ST_LVM_VG: "lvm-vg",
constants.ST_SHARED_FILE: "sharedfile",
}
_STORAGE_TYPE_OPT = \
......
......@@ -654,8 +654,9 @@ def CheckFileBasedStoragePathVsEnabledDiskTemplates(
path should be checked
"""
assert (file_disk_template in
utils.storage.GetDiskTemplatesOfStorageType(constants.ST_FILE))
assert (file_disk_template in utils.storage.GetDiskTemplatesOfStorageTypes(
constants.ST_FILE, constants.ST_SHARED_FILE
))
file_storage_enabled = file_disk_template in enabled_disk_templates
if file_storage_dir is not None:
if file_storage_dir == "":
......@@ -2576,8 +2577,10 @@ class LUClusterVerifyGroup(LogicalUnit, _VerifyErrors):
in case something goes wrong in this verification step
"""
assert (file_disk_template in
utils.storage.GetDiskTemplatesOfStorageType(constants.ST_FILE))
assert (file_disk_template in utils.storage.GetDiskTemplatesOfStorageTypes(
constants.ST_FILE, constants.ST_SHARED_FILE
))
cluster = self.cfg.GetClusterInfo()
if cluster.IsDiskTemplateEnabled(file_disk_template):
self._ErrorIf(
......
......@@ -1104,7 +1104,7 @@ def CheckStorageTypeEnabled(cluster, storage_type):
CheckStorageTypeEnabled(cluster, constants.ST_LVM_VG)
else:
possible_disk_templates = \
utils.storage.GetDiskTemplatesOfStorageType(storage_type)
utils.storage.GetDiskTemplatesOfStorageTypes(storage_type)
for disk_template in possible_disk_templates:
if disk_template in cluster.enabled_disk_templates:
return
......@@ -1174,7 +1174,7 @@ def CheckDiskAccessModeConsistency(parameters, cfg, group=None):
access = parameters[disk_template].get(constants.LDP_ACCESS,
constants.DISK_KERNELSPACE)
if dt not in constants.DTS_HAVE_ACCESS
if disk_template not in constants.DTS_HAVE_ACCESS:
continue
#Check the combination of instance hypervisor, disk template and access
......
......@@ -1112,11 +1112,19 @@ def _GetStorageTypeArgs(cfg, storage_type):
"""
# Special case for file storage
if storage_type == constants.ST_FILE:
# storage.FileStorage wants a list of storage directories
return [[cfg.GetFileStorageDir(), cfg.GetSharedFileStorageDir()]]
return []
if storage_type == constants.ST_FILE:
return [[cfg.GetFileStorageDir()]]
elif storage_type == constants.ST_SHARED_FILE:
dts = cfg.GetClusterInfo().enabled_disk_templates
paths = []
if constants.DT_SHARED_FILE in dts:
paths.append(cfg.GetSharedFileStorageDir())
if constants.DT_GLUSTER in dts:
paths.append(cfg.GetGlusterStorageDir())
return [paths]
else:
return []
class LUNodeModifyStorage(NoHooksLU):
......@@ -1302,13 +1310,14 @@ class LUNodeQueryStorage(NoHooksLU):
self.storage_type = self.op.storage_type
else:
self.storage_type = self._DetermineStorageType()
if self.storage_type not in constants.STS_REPORT:
supported_storage_types = constants.STS_REPORT_NODE_STORAGE
if self.storage_type not in supported_storage_types:
raise errors.OpPrereqError(
"Storage reporting for storage type '%s' is not supported. Please"
" use the --storage-type option to specify one of the supported"
" storage types (%s) or set the default disk template to one that"
" supports storage reporting." %
(self.storage_type, utils.CommaJoin(constants.STS_REPORT)))
(self.storage_type, utils.CommaJoin(supported_storage_types)))
def Exec(self, feedback_fn):
"""Computes the list of nodes and their attributes.
......
......@@ -468,6 +468,7 @@ _STORAGE_TYPES = {
constants.ST_FILE: FileStorage,
constants.ST_LVM_PV: LvmPvStorage,
constants.ST_LVM_VG: LvmVgStorage,
constants.ST_SHARED_FILE: FileStorage,
}
......
......@@ -27,11 +27,11 @@ import logging
from ganeti import constants
def GetDiskTemplatesOfStorageType(storage_type):
def GetDiskTemplatesOfStorageTypes(*storage_types):
"""Given the storage type, returns a list of disk templates based on that
storage type."""
return [dt for dt in constants.DISK_TEMPLATES
if constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[dt] == storage_type]
if constants.MAP_DISK_TEMPLATE_STORAGE_TYPE[dt] in storage_types]
def IsDiskTemplateEnabled(disk_template, enabled_disk_templates):
......
......@@ -519,8 +519,10 @@ def TestClusterModifyFileBasedStorageDir(
# Get some non-file-based disk template to disable file storage
other_disk_template = _GetOtherEnabledDiskTemplate(
utils.storage.GetDiskTemplatesOfStorageType(constants.ST_FILE),
enabled_disk_templates)
utils.storage.GetDiskTemplatesOfStorageTypes(constants.ST_FILE,
constants.ST_SHARED_FILE),
enabled_disk_templates
)
file_storage_dir = qa_config.get(dir_config_key, default_dir)
invalid_file_storage_dir = "/boot/"
......
......@@ -480,9 +480,9 @@ class _QaConfig(object):
"""
enabled_disk_templates = self.GetEnabledDiskTemplates()
if storage_type == constants.ST_LVM_PV:
disk_templates = utils.GetDiskTemplatesOfStorageType(constants.ST_LVM_VG)
disk_templates = utils.GetDiskTemplatesOfStorageTypes(constants.ST_LVM_VG)
else:
disk_templates = utils.GetDiskTemplatesOfStorageType(storage_type)
disk_templates = utils.GetDiskTemplatesOfStorageTypes(storage_type)
return bool(set(enabled_disk_templates).intersection(set(disk_templates)))
def AreSpindlesSupported(self):
......
......@@ -135,7 +135,7 @@ def _DestroyInstanceDisks(instance):
vols = info["volumes"]
for node in info["nodes"]:
AssertCommand(["lvremove", "-f"] + vols, node=node)
elif info["storage-type"] == constants.ST_FILE:
elif info["storage-type"] in (constants.ST_FILE, constants.ST_SHARED_FILE):
# Note that this works for both file and sharedfile, and this is intended.
storage_dir = qa_config.get("file-storage-dir",
pathutils.DEFAULT_FILE_STORAGE_DIR)
......
......@@ -659,6 +659,9 @@ stExt = Types.storageTypeToRaw StorageExt
stFile :: String
stFile = Types.storageTypeToRaw StorageFile
stSharedFile :: String
stSharedFile = Types.storageTypeToRaw StorageSharedFile
stLvmPv :: String
stLvmPv = Types.storageTypeToRaw StorageLvmPv
......@@ -671,13 +674,16 @@ stRados = Types.storageTypeToRaw StorageRados
storageTypes :: FrozenSet String
storageTypes = ConstantUtils.mkSet $ map Types.storageTypeToRaw [minBound..]
-- | The set of storage types for which storage reporting is available
--
-- FIXME: Remove this, once storage reporting is available for all
-- types.
-- | The set of storage types for which full storage reporting is available
stsReport :: FrozenSet String
stsReport = ConstantUtils.mkSet [stFile, stLvmPv, stLvmVg]
-- | The set of storage types for which node storage reporting is available
-- | (as used by LUQueryNodeStorage)
stsReportNodeStorage :: FrozenSet String
stsReportNodeStorage = ConstantUtils.union stsReport $
ConstantUtils.mkSet [stSharedFile]
-- * Storage fields
-- ** First two are valid in LU context only, not passed to backend
......@@ -818,12 +824,12 @@ mapDiskTemplateStorageType =
[(DTBlock, StorageBlock),
(DTDrbd8, StorageLvmVg),
(DTExt, StorageExt),
(DTSharedFile, StorageFile),
(DTSharedFile, StorageSharedFile),
(DTFile, StorageFile),
(DTDiskless, StorageDiskless),
(DTPlain, StorageLvmVg),
(DTRbd, StorageRados),
(DTGluster, StorageFile)]
(DTGluster, StorageSharedFile)]
-- | The set of network-mirrored disk templates
dtsIntMirror :: FrozenSet String
......
......@@ -44,8 +44,6 @@ getDefaultStorageKey cfg T.DTDrbd8 = clusterVolumeGroupName $ configCluster cfg
getDefaultStorageKey cfg T.DTPlain = clusterVolumeGroupName $ configCluster cfg
getDefaultStorageKey cfg T.DTFile =
Just (clusterFileStorageDir $ configCluster cfg)
getDefaultStorageKey cfg T.DTSharedFile =
Just (clusterSharedFileStorageDir $ configCluster cfg)
getDefaultStorageKey _ _ = Nothing
-- | Get the cluster's default spindle storage unit
......
......@@ -459,6 +459,7 @@ $(THH.makeJSONInstance ''OobStatus)
-- | Storage type.
$(THH.declareLADT ''String "StorageType"
[ ("StorageFile", "file")
, ("StorageSharedFile", "sharedfile")
, ("StorageLvmPv", "lvm-pv")
, ("StorageLvmVg", "lvm-vg")
, ("StorageDiskless", "diskless")
......@@ -481,6 +482,7 @@ data StorageUnitRaw = SURaw StorageType StorageKey
-- | Full storage unit with storage-type-specific parameters
data StorageUnit = SUFile StorageKey
| SUSharedFile StorageKey
| SULvmPv StorageKey SPExclusiveStorage
| SULvmVg StorageKey SPExclusiveStorage
| SUDiskless StorageKey
......@@ -491,6 +493,7 @@ data StorageUnit = SUFile StorageKey
instance Show StorageUnit where
show (SUFile key) = showSUSimple StorageFile key
show (SUSharedFile key) = showSUSimple StorageSharedFile key
show (SULvmPv key es) = showSULvm StorageLvmPv key es
show (SULvmVg key es) = showSULvm StorageLvmVg key es
show (SUDiskless key) = showSUSimple StorageDiskless key
......@@ -500,6 +503,7 @@ instance Show StorageUnit where
instance JSON StorageUnit where
showJSON (SUFile key) = showJSON (StorageFile, key, []::[String])
showJSON (SUSharedFile key) = showJSON (StorageSharedFile, key, []::[String])
showJSON (SULvmPv key es) = showJSON (StorageLvmPv, key, [es])
showJSON (SULvmVg key es) = showJSON (StorageLvmVg, key, [es])
showJSON (SUDiskless key) = showJSON (StorageDiskless, key, []::[String])
......@@ -525,13 +529,13 @@ showSULvm st sk es = show (storageTypeToRaw st, sk, [es])
diskTemplateToStorageType :: DiskTemplate -> StorageType
diskTemplateToStorageType DTExt = StorageExt
diskTemplateToStorageType DTFile = StorageFile
diskTemplateToStorageType DTSharedFile = StorageFile
diskTemplateToStorageType DTSharedFile = StorageSharedFile
diskTemplateToStorageType DTDrbd8 = StorageLvmVg
diskTemplateToStorageType DTPlain = StorageLvmVg
diskTemplateToStorageType DTRbd = StorageRados
diskTemplateToStorageType DTDiskless = StorageDiskless
diskTemplateToStorageType DTBlock = StorageBlock
diskTemplateToStorageType DTGluster = StorageFile
diskTemplateToStorageType DTGluster = StorageSharedFile
-- | Equips a raw storage unit with its parameters
addParamsToStorageUnit :: SPExclusiveStorage -> StorageUnitRaw -> StorageUnit
......@@ -539,6 +543,7 @@ addParamsToStorageUnit _ (SURaw StorageBlock key) = SUBlock key
addParamsToStorageUnit _ (SURaw StorageDiskless key) = SUDiskless key
addParamsToStorageUnit _ (SURaw StorageExt key) = SUExt key
addParamsToStorageUnit _ (SURaw StorageFile key) = SUFile key
addParamsToStorageUnit _ (SURaw StorageSharedFile key) = SUSharedFile key
addParamsToStorageUnit es (SURaw StorageLvmPv key) = SULvmPv key es
addParamsToStorageUnit es (SURaw StorageLvmVg key) = SULvmVg key es
addParamsToStorageUnit _ (SURaw StorageRados key) = SURados key
......
......@@ -839,20 +839,22 @@ class TestGetNodeInfo(unittest.TestCase):
class TestSpaceReportingConstants(unittest.TestCase):
"""Ensures consistency between STS_REPORT and backend.
These tests ensure, that the constant 'STS_REPORT' is consitent
These tests ensure, that the constant 'STS_REPORT' is consistent
with the implementation of invoking space reporting functions
in backend.py. Once space reporting is available for all types,
the constant can be removed and these tests as well.
"""
REPORTING = set(constants.STS_REPORT)
NOT_REPORTING = set(constants.STORAGE_TYPES) - REPORTING
def testAllReportingTypesHaveAReportingFunction(self):
for storage_type in constants.STS_REPORT:
for storage_type in TestSpaceReportingConstants.REPORTING:
self.assertTrue(backend._STORAGE_TYPE_INFO_FN[storage_type] is not None)
def testAllNotReportingTypesDoneHaveFunction(self):
non_reporting_types = set(constants.STORAGE_TYPES)\
- set(constants.STS_REPORT)
for storage_type in non_reporting_types:
def testAllNotReportingTypesDontHaveFunction(self):
for storage_type in TestSpaceReportingConstants.NOT_REPORTING:
self.assertEqual(None, backend._STORAGE_TYPE_INFO_FN[storage_type])
......
......@@ -61,7 +61,7 @@ class TestGetStorageUnitForDiskTemplate(unittest.TestCase):
(storage_type, storage_key) = \
storage._GetDefaultStorageUnitForDiskTemplate(self._cfg,
constants.DT_SHARED_FILE)
self.assertEqual(storage_type, constants.ST_FILE)
self.assertEqual(storage_type, constants.ST_SHARED_FILE)
self.assertEqual(storage_key, self._cluster.shared_file_storage_dir)
def testGetDefaultStorageUnitForDiskTemplateDiskless(self):
......@@ -80,7 +80,9 @@ class TestGetStorageUnits(unittest.TestCase):
self._cfg = mock.Mock()
def testGetStorageUnits(self):
disk_templates = constants.DTS_FILEBASED
disk_templates = constants.DTS_FILEBASED - frozenset(
storage.GetDiskTemplatesOfStorageTypes(constants.ST_SHARED_FILE)
)
storage_units = storage.GetStorageUnits(self._cfg, disk_templates)
self.assertEqual(len(storage_units), len(disk_templates))
......
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