Revision 31ccfc0e
b/lib/client/gnt_cluster.py | ||
---|---|---|
1037 | 1037 |
return vg_name |
1038 | 1038 |
|
1039 | 1039 |
|
1040 |
def _GetDrbdHelper(opts): |
|
1040 |
def _GetDrbdHelper(opts, enabled_disk_templates):
|
|
1041 | 1041 |
"""Determine the DRBD usermode helper. |
1042 | 1042 |
|
1043 | 1043 |
""" |
1044 | 1044 |
drbd_helper = opts.drbd_helper |
1045 |
if not opts.drbd_storage and opts.drbd_helper: |
|
1046 |
raise errors.OpPrereqError( |
|
1047 |
"Options --no-drbd-storage and --drbd-usermode-helper conflict.") |
|
1048 |
|
|
1049 |
if not opts.drbd_storage: |
|
1050 |
drbd_helper = "" |
|
1045 |
if enabled_disk_templates: |
|
1046 |
drbd_enabled = constants.DT_DRBD8 in enabled_disk_templates |
|
1047 |
# This raises an exception for historic reasons. It might be a good idea |
|
1048 |
# to allow users to set a DRBD helper when DRBD storage is not enabled. |
|
1049 |
if not drbd_enabled and opts.drbd_helper: |
|
1050 |
raise errors.OpPrereqError( |
|
1051 |
"Setting a DRBD usermode helper when DRBD is not enabled is" |
|
1052 |
" not allowed.") |
|
1051 | 1053 |
return drbd_helper |
1052 | 1054 |
|
1053 | 1055 |
|
... | ... | |
1061 | 1063 |
@return: the desired exit code |
1062 | 1064 |
|
1063 | 1065 |
""" |
1064 |
if not (opts.vg_name is not None or opts.drbd_helper or |
|
1066 |
if not (opts.vg_name is not None or |
|
1067 |
opts.drbd_helper is not None or |
|
1065 | 1068 |
opts.enabled_hypervisors or opts.hvparams or |
1066 | 1069 |
opts.beparams or opts.nicparams or |
1067 | 1070 |
opts.ndparams or opts.diskparams or |
... | ... | |
1096 | 1099 |
vg_name = _GetVgName(opts, enabled_disk_templates) |
1097 | 1100 |
|
1098 | 1101 |
try: |
1099 |
drbd_helper = _GetDrbdHelper(opts) |
|
1102 |
drbd_helper = _GetDrbdHelper(opts, enabled_disk_templates)
|
|
1100 | 1103 |
except errors.OpPrereqError, e: |
1101 | 1104 |
ToStderr(str(e)) |
1102 | 1105 |
return 1 |
b/lib/cmdlib/cluster.py | ||
---|---|---|
851 | 851 |
CheckIpolicyVsDiskTemplates(cluster.ipolicy, |
852 | 852 |
enabled_disk_templates) |
853 | 853 |
|
854 |
def _CheckDrbdHelper(self, node_uuids): |
|
854 |
def _CheckDrbdHelperOnNodes(self, drbd_helper, node_uuids): |
|
855 |
"""Checks whether the set DRBD helper actually exists on the nodes. |
|
856 |
|
|
857 |
@type drbd_helper: string |
|
858 |
@param drbd_helper: path of the drbd usermode helper binary |
|
859 |
@type node_uuids: list of strings |
|
860 |
@param node_uuids: list of node UUIDs to check for the helper |
|
861 |
|
|
862 |
""" |
|
863 |
# checks given drbd helper on all nodes |
|
864 |
helpers = self.rpc.call_drbd_helper(node_uuids) |
|
865 |
for (_, ninfo) in self.cfg.GetMultiNodeInfo(node_uuids): |
|
866 |
if ninfo.offline: |
|
867 |
self.LogInfo("Not checking drbd helper on offline node %s", |
|
868 |
ninfo.name) |
|
869 |
continue |
|
870 |
msg = helpers[ninfo.uuid].fail_msg |
|
871 |
if msg: |
|
872 |
raise errors.OpPrereqError("Error checking drbd helper on node" |
|
873 |
" '%s': %s" % (ninfo.name, msg), |
|
874 |
errors.ECODE_ENVIRON) |
|
875 |
node_helper = helpers[ninfo.uuid].payload |
|
876 |
if node_helper != drbd_helper: |
|
877 |
raise errors.OpPrereqError("Error on node '%s': drbd helper is %s" % |
|
878 |
(ninfo.name, node_helper), |
|
879 |
errors.ECODE_ENVIRON) |
|
880 |
|
|
881 |
def _CheckDrbdHelper(self, node_uuids, drbd_enabled, drbd_gets_enabled): |
|
855 | 882 |
"""Check the DRBD usermode helper. |
856 | 883 |
|
857 | 884 |
@type node_uuids: list of strings |
858 | 885 |
@param node_uuids: a list of nodes' UUIDs |
886 |
@type drbd_enabled: boolean |
|
887 |
@param drbd_enabled: whether DRBD will be enabled after this operation |
|
888 |
(no matter if it was disabled before or not) |
|
889 |
@type drbd_gets_enabled: boolen |
|
890 |
@param drbd_gets_enabled: true if DRBD was disabled before this |
|
891 |
operation, but will be enabled afterwards |
|
859 | 892 |
|
860 | 893 |
""" |
861 |
if self.op.drbd_helper is not None and not self.op.drbd_helper: |
|
894 |
if self.op.drbd_helper == '': |
|
895 |
if drbd_enabled: |
|
896 |
raise errors.OpPrereqError("Cannot disable drbd helper while" |
|
897 |
" DRBD is enabled.") |
|
862 | 898 |
if self.cfg.HasAnyDiskOfType(constants.LD_DRBD8): |
863 | 899 |
raise errors.OpPrereqError("Cannot disable drbd helper while" |
864 | 900 |
" drbd-based instances exist", |
865 | 901 |
errors.ECODE_INVAL) |
866 | 902 |
|
867 |
if self.op.drbd_helper: |
|
868 |
# checks given drbd helper on all nodes |
|
869 |
helpers = self.rpc.call_drbd_helper(node_uuids) |
|
870 |
for (_, ninfo) in self.cfg.GetMultiNodeInfo(node_uuids): |
|
871 |
if ninfo.offline: |
|
872 |
self.LogInfo("Not checking drbd helper on offline node %s", |
|
873 |
ninfo.name) |
|
874 |
continue |
|
875 |
msg = helpers[ninfo.uuid].fail_msg |
|
876 |
if msg: |
|
877 |
raise errors.OpPrereqError("Error checking drbd helper on node" |
|
878 |
" '%s': %s" % (ninfo.name, msg), |
|
879 |
errors.ECODE_ENVIRON) |
|
880 |
node_helper = helpers[ninfo.uuid].payload |
|
881 |
if node_helper != self.op.drbd_helper: |
|
882 |
raise errors.OpPrereqError("Error on node '%s': drbd helper is %s" % |
|
883 |
(ninfo.name, node_helper), |
|
884 |
errors.ECODE_ENVIRON) |
|
903 |
else: |
|
904 |
if self.op.drbd_helper is not None and drbd_enabled: |
|
905 |
self._CheckDrbdHelperOnNodes(self.op.drbd_helper, node_uuids) |
|
906 |
else: |
|
907 |
if drbd_gets_enabled: |
|
908 |
current_drbd_helper = self.cfg.GetClusterInfo().drbd_usermode_helper |
|
909 |
if current_drbd_helper is not None: |
|
910 |
self._CheckDrbdHelperOnNodes(current_drbd_helper, node_uuids) |
|
911 |
else: |
|
912 |
raise errors.OpPrereqError("Cannot enable DRBD without a" |
|
913 |
" DRBD usermode helper set.") |
|
885 | 914 |
|
886 | 915 |
def CheckPrereq(self): |
887 | 916 |
"""Check prerequisites. |
... | ... | |
912 | 941 |
self.LogWarning, self.op.shared_file_storage_dir, |
913 | 942 |
enabled_disk_templates) |
914 | 943 |
|
915 |
self._CheckDrbdHelper(node_uuids) |
|
944 |
drbd_enabled = constants.DT_DRBD8 in enabled_disk_templates |
|
945 |
drbd_gets_enabled = constants.DT_DRBD8 in new_enabled_disk_templates |
|
946 |
self._CheckDrbdHelper(node_uuids, drbd_enabled, drbd_gets_enabled) |
|
916 | 947 |
|
917 | 948 |
# validate params changes |
918 | 949 |
if self.op.beparams: |
b/test/py/cmdlib/cluster_unittest.py | ||
---|---|---|
501 | 501 |
|
502 | 502 |
self.mcpu.assertLogContainsRegex("but did not enable") |
503 | 503 |
|
504 |
def testResetDrbdHelper(self): |
|
504 |
def testResetDrbdHelperDrbdDisabled(self):
|
|
505 | 505 |
drbd_helper = "" |
506 | 506 |
self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS]) |
507 | 507 |
op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper) |
... | ... | |
509 | 509 |
|
510 | 510 |
self.assertEqual(None, self.cluster.drbd_usermode_helper) |
511 | 511 |
|
512 |
def testResetDrbdHelperDrbdEnabled(self): |
|
513 |
drbd_helper = "" |
|
514 |
self.cluster.enabled_disk_templates = [constants.DT_DRBD8] |
|
515 |
op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper) |
|
516 |
self.ExecOpCodeExpectOpPrereqError( |
|
517 |
op, "Cannot disable drbd helper while DRBD is enabled.") |
|
518 |
|
|
519 |
def testEnableDrbdNoHelper(self): |
|
520 |
self.cluster.enabled_disk_templates = [constants.DT_DISKLESS] |
|
521 |
self.cluster.drbd_usermode_helper = None |
|
522 |
enabled_disk_templates = [constants.DT_DRBD8] |
|
523 |
op = opcodes.OpClusterSetParams( |
|
524 |
enabled_disk_templates=enabled_disk_templates) |
|
525 |
self.ExecOpCodeExpectOpPrereqError( |
|
526 |
op, "Cannot enable DRBD without a DRBD usermode helper set") |
|
527 |
|
|
528 |
def testEnableDrbdHelperSet(self): |
|
529 |
drbd_helper = "/bin/random_helper" |
|
530 |
self.rpc.call_drbd_helper.return_value = \ |
|
531 |
self.RpcResultsBuilder() \ |
|
532 |
.AddSuccessfulNode(self.master, drbd_helper) \ |
|
533 |
.Build() |
|
534 |
self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS]) |
|
535 |
self.cluster.drbd_usermode_helper = drbd_helper |
|
536 |
enabled_disk_templates = [constants.DT_DRBD8] |
|
537 |
op = opcodes.OpClusterSetParams( |
|
538 |
enabled_disk_templates=enabled_disk_templates, |
|
539 |
ipolicy={constants.IPOLICY_DTS: enabled_disk_templates}) |
|
540 |
self.ExecOpCode(op) |
|
541 |
|
|
542 |
self.assertEqual(drbd_helper, self.cluster.drbd_usermode_helper) |
|
543 |
|
|
512 | 544 |
def testDrbdHelperAlreadySet(self): |
513 | 545 |
drbd_helper = "/bin/true" |
514 | 546 |
self.rpc.call_drbd_helper.return_value = \ |
515 | 547 |
self.RpcResultsBuilder() \ |
516 | 548 |
.AddSuccessfulNode(self.master, "/bin/true") \ |
517 | 549 |
.Build() |
518 |
self.cluster.enabled_disk_templates = [constants.DT_DISKLESS]
|
|
550 |
self.cfg.SetEnabledDiskTemplates([constants.DT_DISKLESS])
|
|
519 | 551 |
op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper) |
520 | 552 |
self.ExecOpCode(op) |
521 | 553 |
|
... | ... | |
529 | 561 |
.AddSuccessfulNode(self.master, "/bin/true") \ |
530 | 562 |
.Build() |
531 | 563 |
self.cluster.drbd_usermode_helper = "/bin/false" |
532 |
self.cluster.enabled_disk_templates = [constants.DT_DRBD8]
|
|
564 |
self.cfg.SetEnabledDiskTemplates([constants.DT_DRBD8])
|
|
533 | 565 |
op = opcodes.OpClusterSetParams(drbd_helper=drbd_helper) |
534 | 566 |
self.ExecOpCode(op) |
535 | 567 |
|
b/test/py/ganeti.client.gnt_cluster_unittest.py | ||
---|---|---|
260 | 260 |
self.assertEqual(result, constants.EXIT_FAILURE) |
261 | 261 |
|
262 | 262 |
|
263 |
class InitDrbdHelper(unittest.TestCase):
|
|
263 |
class DrbdHelperTestCase(unittest.TestCase):
|
|
264 | 264 |
|
265 | 265 |
def setUp(self): |
266 | 266 |
unittest.TestCase.setUp(self) |
... | ... | |
272 | 272 |
def disableDrbd(self): |
273 | 273 |
self.enabled_disk_templates = [constants.DT_DISKLESS] |
274 | 274 |
|
275 |
|
|
276 |
class InitDrbdHelper(DrbdHelperTestCase): |
|
277 |
|
|
275 | 278 |
def testNoDrbdNoHelper(self): |
276 | 279 |
opts = mock.Mock() |
277 | 280 |
opts.drbd_helper = None |
... | ... | |
308 | 311 |
self.assertEquals(opts.drbd_helper, helper) |
309 | 312 |
|
310 | 313 |
|
311 |
class GetDrbdHelper(unittest.TestCase):
|
|
314 |
class GetDrbdHelper(DrbdHelperTestCase):
|
|
312 | 315 |
|
313 | 316 |
def testNoDrbdNoHelper(self): |
314 | 317 |
opts = mock.Mock() |
315 |
opts.drbd_storage = False |
|
318 |
self.disableDrbd() |
|
319 |
opts.drbd_helper = None |
|
320 |
helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates) |
|
321 |
self.assertEquals(None, helper) |
|
322 |
|
|
323 |
def testNoTemplateInfoNoHelper(self): |
|
324 |
opts = mock.Mock() |
|
316 | 325 |
opts.drbd_helper = None |
317 |
helper = gnt_cluster._GetDrbdHelper(opts) |
|
318 |
self.assertEquals("", helper) |
|
326 |
helper = gnt_cluster._GetDrbdHelper(opts, None) |
|
327 |
self.assertEquals(None, helper) |
|
328 |
|
|
329 |
def testNoTemplateInfoHelper(self): |
|
330 |
opts = mock.Mock() |
|
331 |
opts.drbd_helper = "/bin/true" |
|
332 |
helper = gnt_cluster._GetDrbdHelper(opts, None) |
|
333 |
self.assertEquals(opts.drbd_helper, helper) |
|
319 | 334 |
|
320 | 335 |
def testNoDrbdHelper(self): |
321 | 336 |
opts = mock.Mock() |
322 |
opts.drbd_storage = None
|
|
337 |
self.disableDrbd()
|
|
323 | 338 |
opts.drbd_helper = "/bin/true" |
324 |
self.assertRaises(errors.OpPrereqError, gnt_cluster._GetDrbdHelper, opts) |
|
339 |
self.assertRaises(errors.OpPrereqError, gnt_cluster._GetDrbdHelper, opts, |
|
340 |
self.enabled_disk_templates) |
|
325 | 341 |
|
326 | 342 |
def testDrbdNoHelper(self): |
327 | 343 |
opts = mock.Mock() |
328 |
opts.drbd_storage = True
|
|
344 |
self.enableDrbd()
|
|
329 | 345 |
opts.drbd_helper = None |
330 |
helper = gnt_cluster._GetDrbdHelper(opts) |
|
346 |
helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates)
|
|
331 | 347 |
self.assertEquals(None, helper) |
332 | 348 |
|
333 | 349 |
def testDrbdHelper(self): |
334 | 350 |
opts = mock.Mock() |
335 |
opts.drbd_storage = True
|
|
351 |
self.enableDrbd()
|
|
336 | 352 |
opts.drbd_helper = "/bin/true" |
337 |
helper = gnt_cluster._GetDrbdHelper(opts) |
|
353 |
helper = gnt_cluster._GetDrbdHelper(opts, self.enabled_disk_templates)
|
|
338 | 354 |
self.assertEquals(opts.drbd_helper, helper) |
339 | 355 |
|
340 | 356 |
|
Also available in: Unified diff