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