Revision 294254b1
b/lib/cmdlib/cluster.py | ||
---|---|---|
57 | 57 |
GetUpdatedIPolicy, ComputeNewInstanceViolations, GetUpdatedParams, \ |
58 | 58 |
CheckOSParams, CheckHVParams, AdjustCandidatePool, CheckNodePVs, \ |
59 | 59 |
ComputeIPolicyInstanceViolation, AnnotateDiskParams, SupportsOob, \ |
60 |
CheckIpolicyVsDiskTemplates |
|
60 |
CheckIpolicyVsDiskTemplates, CheckDiskAccessModeValidity, \ |
|
61 |
CheckDiskAccessModeConsistency |
|
61 | 62 |
|
62 | 63 |
import ganeti.masterd.instance |
63 | 64 |
|
... | ... | |
704 | 705 |
utils.ForceDictType(dt_params, constants.DISK_DT_TYPES) |
705 | 706 |
try: |
706 | 707 |
utils.VerifyDictOptions(self.op.diskparams, constants.DISK_DT_DEFAULTS) |
708 |
CheckDiskAccessModeValidity(self.op.diskparams) |
|
707 | 709 |
except errors.OpPrereqError, err: |
708 | 710 |
raise errors.OpPrereqError("While verify diskparams options: %s" % err, |
709 | 711 |
errors.ECODE_INVAL) |
... | ... | |
1024 | 1026 |
self.new_diskparams[dt_name] = dt_params |
1025 | 1027 |
else: |
1026 | 1028 |
self.new_diskparams[dt_name].update(dt_params) |
1029 |
CheckDiskAccessModeConsistency(self.op.diskparams, self.cfg) |
|
1027 | 1030 |
|
1028 | 1031 |
# os hypervisor parameters |
1029 | 1032 |
self.new_os_hvp = objects.FillDict(cluster.os_hvp, {}) |
b/lib/cmdlib/common.py | ||
---|---|---|
1133 | 1133 |
raise errors.OpPrereqError("The following disk template are allowed" |
1134 | 1134 |
" by the ipolicy, but not enabled on the" |
1135 | 1135 |
" cluster: %s" % utils.CommaJoin(not_enabled)) |
1136 |
|
|
1137 |
|
|
1138 |
def CheckDiskAccessModeValidity(parameters): |
|
1139 |
"""Checks if the access parameter is legal. |
|
1140 |
|
|
1141 |
@see: L{CheckDiskAccessModeConsistency} for cluster consistency checks. |
|
1142 |
@raise errors.OpPrereqError: if the check fails. |
|
1143 |
|
|
1144 |
""" |
|
1145 |
if constants.DT_RBD in parameters: |
|
1146 |
access = parameters[constants.DT_RBD].get(constants.RBD_ACCESS, |
|
1147 |
constants.DISK_KERNELSPACE) |
|
1148 |
if access not in constants.DISK_VALID_ACCESS_MODES: |
|
1149 |
valid_vals_str = utils.CommaJoin(constants.DISK_VALID_ACCESS_MODES) |
|
1150 |
raise errors.OpPrereqError("Invalid value of '{d}:{a}': '{v}' (expected" |
|
1151 |
" one of {o})".format(d=constants.DT_RBD, |
|
1152 |
a=constants.RBD_ACCESS, |
|
1153 |
v=access, |
|
1154 |
o=valid_vals_str)) |
|
1155 |
|
|
1156 |
|
|
1157 |
def CheckDiskAccessModeConsistency(parameters, cfg, group=None): |
|
1158 |
"""Checks if the access param is consistent with the cluster configuration. |
|
1159 |
|
|
1160 |
@note: requires a configuration lock to run. |
|
1161 |
@param parameters: the parameters to validate |
|
1162 |
@param cfg: the cfg object of the cluster |
|
1163 |
@param group: if set, only check for consistency within this group. |
|
1164 |
@raise errors.OpPrereqError: if the LU attempts to change the access parameter |
|
1165 |
to an invalid value, such as "pink bunny". |
|
1166 |
@raise errors.OpPrereqError: if the LU attempts to change the access parameter |
|
1167 |
to an inconsistent value, such as asking for RBD |
|
1168 |
userspace access to the chroot hypervisor. |
|
1169 |
|
|
1170 |
""" |
|
1171 |
CheckDiskAccessModeValidity(parameters) |
|
1172 |
|
|
1173 |
if constants.DT_RBD in parameters: |
|
1174 |
access = parameters[constants.DT_RBD].get(constants.RBD_ACCESS, |
|
1175 |
constants.DISK_KERNELSPACE) |
|
1176 |
|
|
1177 |
#Check the combination of instance hypervisor, disk template and access |
|
1178 |
#protocol is sane. |
|
1179 |
inst_uuids = cfg.GetNodeGroupInstances(group) if group else \ |
|
1180 |
cfg.GetInstanceList() |
|
1181 |
|
|
1182 |
for entry in inst_uuids: |
|
1183 |
#hyp, disk, access |
|
1184 |
inst = cfg.GetInstanceInfo(entry) |
|
1185 |
hv = inst.hypervisor |
|
1186 |
dt = inst.disk_template |
|
1187 |
|
|
1188 |
#do not check for disk types that don't have this setting. |
|
1189 |
if dt != constants.DT_RBD: |
|
1190 |
continue |
|
1191 |
|
|
1192 |
if not IsValidDiskAccessModeCombination(hv, dt, access): |
|
1193 |
raise errors.OpPrereqError("Instance {i}: cannot use '{a}' access" |
|
1194 |
" setting with {h} hypervisor and {d} disk" |
|
1195 |
" type.".format(i=inst.name, |
|
1196 |
a=access, |
|
1197 |
h=hv, |
|
1198 |
d=dt)) |
|
1199 |
|
|
1200 |
|
|
1201 |
def IsValidDiskAccessModeCombination(hv, disk_template, mode): |
|
1202 |
"""Checks if an hypervisor can read a disk template with given mode. |
|
1203 |
|
|
1204 |
@param hv: the hypervisor that will access the data |
|
1205 |
@param disk_template: the disk template the data is stored as |
|
1206 |
@param mode: how the hypervisor should access the data |
|
1207 |
@return: True if the hypervisor can read a given read disk_template |
|
1208 |
in the specified mode. |
|
1209 |
|
|
1210 |
""" |
|
1211 |
if mode == constants.DISK_KERNELSPACE: |
|
1212 |
return True |
|
1213 |
|
|
1214 |
if (hv == constants.HT_KVM and |
|
1215 |
disk_template == constants.DT_RBD and |
|
1216 |
mode == constants.DISK_USERSPACE): |
|
1217 |
return True |
|
1218 |
|
|
1219 |
# Everything else: |
|
1220 |
return False |
b/lib/cmdlib/group.py | ||
---|---|---|
39 | 39 |
CheckNodeGroupInstances, GetUpdatedIPolicy, \ |
40 | 40 |
ComputeNewInstanceViolations, GetDefaultIAllocator, ShareAll, \ |
41 | 41 |
CheckInstancesNodeGroups, LoadNodeEvacResult, MapInstanceLvsToNodes, \ |
42 |
CheckIpolicyVsDiskTemplates |
|
42 |
CheckIpolicyVsDiskTemplates, CheckDiskAccessModeValidity, \ |
|
43 |
CheckDiskAccessModeConsistency |
|
43 | 44 |
|
44 | 45 |
import ganeti.masterd.instance |
45 | 46 |
|
... | ... | |
406 | 407 |
raise errors.OpPrereqError("Please pass at least one modification", |
407 | 408 |
errors.ECODE_INVAL) |
408 | 409 |
|
410 |
if self.op.diskparams: |
|
411 |
CheckDiskAccessModeValidity(self.op.diskparams) |
|
412 |
|
|
409 | 413 |
def ExpandNames(self): |
410 | 414 |
# This raises errors.OpPrereqError on its own: |
411 | 415 |
self.group_uuid = self.cfg.LookupNodeGroup(self.op.group_name) |
... | ... | |
500 | 504 |
# As we've all subdicts of diskparams ready, lets merge the actual |
501 | 505 |
# dict with all updated subdicts |
502 | 506 |
self.new_diskparams = objects.FillDict(diskparams, new_diskparams) |
507 |
|
|
503 | 508 |
try: |
504 | 509 |
utils.VerifyDictOptions(self.new_diskparams, constants.DISK_DT_DEFAULTS) |
510 |
CheckDiskAccessModeConsistency(self.new_diskparams, self.cfg, |
|
511 |
group=self.group) |
|
505 | 512 |
except errors.OpPrereqError, err: |
506 | 513 |
raise errors.OpPrereqError("While verify diskparams options: %s" % err, |
507 | 514 |
errors.ECODE_INVAL) |
b/lib/cmdlib/instance.py | ||
---|---|---|
49 | 49 |
IsExclusiveStorageEnabledNode, CheckHVParams, CheckOSParams, \ |
50 | 50 |
AnnotateDiskParams, GetUpdatedParams, ExpandInstanceUuidAndName, \ |
51 | 51 |
ComputeIPolicySpecViolation, CheckInstanceState, ExpandNodeUuidAndName, \ |
52 |
CheckDiskTemplateEnabled |
|
52 |
CheckDiskTemplateEnabled, IsValidDiskAccessModeCombination
|
|
53 | 53 |
from ganeti.cmdlib.instance_storage import CreateDisks, \ |
54 | 54 |
CheckNodesFreeDiskPerVG, WipeDisks, WipeOrCleanupDisks, WaitForSync, \ |
55 | 55 |
IsExclusiveStorageEnabledNodeUuid, CreateSingleBlockDev, ComputeDisks, \ |
... | ... | |
1168 | 1168 |
dsk[constants.IDISK_SIZE] = \ |
1169 | 1169 |
int(float(node_disks[dsk[constants.IDISK_ADOPT]])) |
1170 | 1170 |
|
1171 |
# Check disk access param to be compatible with specified hypervisor |
|
1172 |
node_info = self.cfg.GetNodeInfo(self.op.pnode_uuid) |
|
1173 |
node_group = self.cfg.GetNodeGroup(node_info.group) |
|
1174 |
disk_params = self.cfg.GetGroupDiskParams(node_group) |
|
1175 |
access_type = disk_params[self.op.disk_template].get( |
|
1176 |
constants.RBD_ACCESS, constants.DISK_KERNELSPACE |
|
1177 |
) |
|
1178 |
|
|
1179 |
if not IsValidDiskAccessModeCombination(self.op.hypervisor, |
|
1180 |
self.op.disk_template, |
|
1181 |
access_type): |
|
1182 |
raise errors.OpPrereqError("Selected hypervisor (%s) cannot be" |
|
1183 |
" used with %s disk access param" % |
|
1184 |
(self.op.hypervisor, access_type), |
|
1185 |
errors.ECODE_STATE) |
|
1186 |
|
|
1171 | 1187 |
# Verify instance specs |
1172 | 1188 |
spindle_use = self.be_full.get(constants.BE_SPINDLE_USE, None) |
1173 | 1189 |
ispec = { |
b/lib/config.py | ||
---|---|---|
667 | 667 |
constants.NDS_PARAMETER_TYPES) |
668 | 668 |
_helper_ipolicy("cluster", cluster.ipolicy, True) |
669 | 669 |
|
670 |
if constants.DT_RBD in cluster.diskparams: |
|
671 |
access = cluster.diskparams[constants.DT_RBD][constants.RBD_ACCESS] |
|
672 |
if access not in constants.DISK_VALID_ACCESS_MODES: |
|
673 |
result.append( |
|
674 |
"Invalid value of '%s:%s': '%s' (expected one of %s)" % ( |
|
675 |
constants.DT_RBD, constants.RBD_ACCESS, access, |
|
676 |
utils.CommaJoin(constants.DISK_VALID_ACCESS_MODES) |
|
677 |
) |
|
678 |
) |
|
679 |
|
|
670 | 680 |
# per-instance checks |
671 | 681 |
for instance_uuid in data.instances: |
672 | 682 |
instance = data.instances[instance_uuid] |
Also available in: Unified diff