Revision a8e3e009

b/lib/cmdlib.py
8678 8678
  return drbd_dev
8679 8679

  
8680 8680

  
8681
def _GenerateDiskTemplate(lu, template_name,
8682
                          instance_name, primary_node,
8683
                          secondary_nodes, disk_info,
8684
                          file_storage_dir, file_driver,
8685
                          base_index, feedback_fn, disk_params):
8681
def _GenerateDiskTemplate(lu, template_name, instance_name, primary_node,
8682
    secondary_nodes, disk_info, file_storage_dir, file_driver, base_index,
8683
    feedback_fn, disk_params,
8684
    _req_file_storage=opcodes.RequireFileStorage,
8685
    _req_shr_file_storage=opcodes.RequireSharedFileStorage):
8686 8686
  """Generate the entire disk layout for a given template type.
8687 8687

  
8688 8688
  """
......
8742 8742
    if secondary_nodes:
8743 8743
      raise errors.ProgrammerError("Wrong template configuration")
8744 8744

  
8745
    opcodes.RequireFileStorage()
8745
    _req_file_storage()
8746 8746

  
8747 8747
    for idx, disk in enumerate(disk_info):
8748 8748
      disk_index = idx + base_index
......
8759 8759
    if secondary_nodes:
8760 8760
      raise errors.ProgrammerError("Wrong template configuration")
8761 8761

  
8762
    opcodes.RequireSharedFileStorage()
8762
    _req_shr_file_storage()
8763 8763

  
8764 8764
    for idx, disk in enumerate(disk_info):
8765 8765
      disk_index = idx + base_index
b/test/ganeti.cmdlib_unittest.py
382 382

  
383 383

  
384 384
class _FakeLU:
385
  def __init__(self, cfg=NotImplemented):
385
  def __init__(self, cfg=NotImplemented, proc=NotImplemented):
386 386
    self.warning_log = []
387 387
    self.info_log = []
388 388
    self.cfg = cfg
389
    self.proc = proc
389 390

  
390 391
  def LogWarning(self, text, *args):
391 392
    self.warning_log.append((text, args))
......
904 905
      ])
905 906

  
906 907

  
908
class _FakeConfigForGenDiskTemplate:
909
  def __init__(self):
910
    self._unique_id = itertools.count()
911
    self._drbd_minor = itertools.count(20)
912
    self._port = itertools.count(constants.FIRST_DRBD_PORT)
913
    self._secret = itertools.count()
914

  
915
  def GetVGName(self):
916
    return "testvg"
917

  
918
  def GenerateUniqueID(self, ec_id):
919
    return "ec%s-uq%s" % (ec_id, self._unique_id.next())
920

  
921
  def AllocateDRBDMinor(self, nodes, instance):
922
    return [self._drbd_minor.next()
923
            for _ in nodes]
924

  
925
  def AllocatePort(self):
926
    return self._port.next()
927

  
928
  def GenerateDRBDSecret(self, ec_id):
929
    return "ec%s-secret%s" % (ec_id, self._secret.next())
930

  
931

  
932
class _FakeProcForGenDiskTemplate:
933
  def GetECId(self):
934
    return 0
935

  
936

  
937
class TestGenerateDiskTemplate(unittest.TestCase):
938
  def setUp(self):
939
    nodegroup = objects.NodeGroup(name="ng")
940
    nodegroup.UpgradeConfig()
941

  
942
    cfg = _FakeConfigForGenDiskTemplate()
943
    proc = _FakeProcForGenDiskTemplate()
944

  
945
    self.lu = _FakeLU(cfg=cfg, proc=proc)
946
    self.nodegroup = nodegroup
947

  
948
  def testWrongDiskTemplate(self):
949
    gdt = cmdlib._GenerateDiskTemplate
950
    disk_template = "##unknown##"
951

  
952
    assert disk_template not in constants.DISK_TEMPLATES
953

  
954
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, disk_template,
955
                      "inst26831.example.com", "node30113.example.com", [], [],
956
                      NotImplemented, NotImplemented, 0, self.lu.LogInfo,
957
                      self.nodegroup.diskparams)
958

  
959
  def testDiskless(self):
960
    gdt = cmdlib._GenerateDiskTemplate
961

  
962
    result = gdt(self.lu, constants.DT_DISKLESS, "inst27734.example.com",
963
                 "node30113.example.com", [], [],
964
                 NotImplemented, NotImplemented, 0, self.lu.LogInfo,
965
                 self.nodegroup.diskparams)
966
    self.assertEqual(result, [])
967

  
968
  def _TestTrivialDisk(self, template, disk_info, base_index, exp_dev_type,
969
                       file_storage_dir=NotImplemented,
970
                       file_driver=NotImplemented,
971
                       req_file_storage=NotImplemented,
972
                       req_shr_file_storage=NotImplemented):
973
    gdt = cmdlib._GenerateDiskTemplate
974

  
975
    map(lambda params: utils.ForceDictType(params,
976
                                           constants.IDISK_PARAMS_TYPES),
977
        disk_info)
978

  
979
    # Check if non-empty list of secondaries is rejected
980
    self.assertRaises(errors.ProgrammerError, gdt, self.lu,
981
                      template, "inst25088.example.com",
982
                      "node185.example.com", ["node323.example.com"], [],
983
                      NotImplemented, NotImplemented, base_index,
984
                      self.lu.LogInfo, self.nodegroup.diskparams,
985
                      _req_file_storage=req_file_storage,
986
                      _req_shr_file_storage=req_shr_file_storage)
987

  
988
    result = gdt(self.lu, template, "inst21662.example.com",
989
                 "node21741.example.com", [],
990
                 disk_info, file_storage_dir, file_driver, base_index,
991
                 self.lu.LogInfo, self.nodegroup.diskparams,
992
                 _req_file_storage=req_file_storage,
993
                 _req_shr_file_storage=req_shr_file_storage)
994

  
995
    for (idx, disk) in enumerate(result):
996
      self.assertTrue(isinstance(disk, objects.Disk))
997
      self.assertEqual(disk.dev_type, exp_dev_type)
998
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
999
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1000
      self.assertTrue(disk.children is None)
1001

  
1002
    self.assertEqual(map(operator.attrgetter("iv_name"), result),
1003
      ["disk/%s" % i for i in range(base_index, base_index + len(disk_info))])
1004

  
1005
    return result
1006

  
1007
  def testPlain(self):
1008
    disk_info = [{
1009
      constants.IDISK_SIZE: 1024,
1010
      constants.IDISK_MODE: constants.DISK_RDWR,
1011
      }, {
1012
      constants.IDISK_SIZE: 4096,
1013
      constants.IDISK_VG: "othervg",
1014
      constants.IDISK_MODE: constants.DISK_RDWR,
1015
      }]
1016

  
1017
    result = self._TestTrivialDisk(constants.DT_PLAIN, disk_info, 3,
1018
                                   constants.LD_LV)
1019

  
1020
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1021
      ("testvg", "ec0-uq0.disk3"),
1022
      ("othervg", "ec0-uq1.disk4"),
1023
      ])
1024

  
1025
  @staticmethod
1026
  def _AllowFileStorage():
1027
    pass
1028

  
1029
  @staticmethod
1030
  def _ForbidFileStorage():
1031
    raise errors.OpPrereqError("Disallowed in test")
1032

  
1033
  def testFile(self):
1034
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1035
                      constants.DT_FILE, [], 0, NotImplemented,
1036
                      req_file_storage=self._ForbidFileStorage)
1037
    self.assertRaises(errors.OpPrereqError, self._TestTrivialDisk,
1038
                      constants.DT_SHARED_FILE, [], 0, NotImplemented,
1039
                      req_shr_file_storage=self._ForbidFileStorage)
1040

  
1041
    for disk_template in [constants.DT_FILE, constants.DT_SHARED_FILE]:
1042
      disk_info = [{
1043
        constants.IDISK_SIZE: 80 * 1024,
1044
        constants.IDISK_MODE: constants.DISK_RDONLY,
1045
        }, {
1046
        constants.IDISK_SIZE: 4096,
1047
        constants.IDISK_MODE: constants.DISK_RDWR,
1048
        }, {
1049
        constants.IDISK_SIZE: 6 * 1024,
1050
        constants.IDISK_MODE: constants.DISK_RDWR,
1051
        }]
1052

  
1053
      result = self._TestTrivialDisk(disk_template, disk_info, 2,
1054
        constants.LD_FILE, file_storage_dir="/tmp",
1055
        file_driver=constants.FD_BLKTAP,
1056
        req_file_storage=self._AllowFileStorage,
1057
        req_shr_file_storage=self._AllowFileStorage)
1058

  
1059
      self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1060
        (constants.FD_BLKTAP, "/tmp/disk2"),
1061
        (constants.FD_BLKTAP, "/tmp/disk3"),
1062
        (constants.FD_BLKTAP, "/tmp/disk4"),
1063
        ])
1064

  
1065
  def testBlock(self):
1066
    disk_info = [{
1067
      constants.IDISK_SIZE: 8 * 1024,
1068
      constants.IDISK_MODE: constants.DISK_RDWR,
1069
      constants.IDISK_ADOPT: "/tmp/some/block/dev",
1070
      }]
1071

  
1072
    result = self._TestTrivialDisk(constants.DT_BLOCK, disk_info, 10,
1073
                                   constants.LD_BLOCKDEV)
1074

  
1075
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1076
      (constants.BLOCKDEV_DRIVER_MANUAL, "/tmp/some/block/dev"),
1077
      ])
1078

  
1079
  def testRbd(self):
1080
    disk_info = [{
1081
      constants.IDISK_SIZE: 8 * 1024,
1082
      constants.IDISK_MODE: constants.DISK_RDONLY,
1083
      }, {
1084
      constants.IDISK_SIZE: 100 * 1024,
1085
      constants.IDISK_MODE: constants.DISK_RDWR,
1086
      }]
1087

  
1088
    result = self._TestTrivialDisk(constants.DT_RBD, disk_info, 0,
1089
                                   constants.LD_RBD)
1090

  
1091
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1092
      ("rbd", "ec0-uq0.rbd.disk0"),
1093
      ("rbd", "ec0-uq1.rbd.disk1"),
1094
      ])
1095

  
1096
  def testDrbd8(self):
1097
    gdt = cmdlib._GenerateDiskTemplate
1098
    drbd8_defaults = constants.DISK_LD_DEFAULTS[constants.LD_DRBD8]
1099
    drbd8_default_metavg = drbd8_defaults[constants.LDP_DEFAULT_METAVG]
1100

  
1101
    disk_info = [{
1102
      constants.IDISK_SIZE: 1024,
1103
      constants.IDISK_MODE: constants.DISK_RDWR,
1104
      }, {
1105
      constants.IDISK_SIZE: 100 * 1024,
1106
      constants.IDISK_MODE: constants.DISK_RDONLY,
1107
      constants.IDISK_METAVG: "metavg",
1108
      }, {
1109
      constants.IDISK_SIZE: 4096,
1110
      constants.IDISK_MODE: constants.DISK_RDWR,
1111
      constants.IDISK_VG: "vgxyz",
1112
      },
1113
      ]
1114

  
1115
    exp_logical_ids = [[
1116
      (self.lu.cfg.GetVGName(), "ec0-uq0.disk0_data"),
1117
      (drbd8_default_metavg, "ec0-uq0.disk0_meta"),
1118
      ], [
1119
      (self.lu.cfg.GetVGName(), "ec0-uq1.disk1_data"),
1120
      ("metavg", "ec0-uq1.disk1_meta"),
1121
      ], [
1122
      ("vgxyz", "ec0-uq2.disk2_data"),
1123
      (drbd8_default_metavg, "ec0-uq2.disk2_meta"),
1124
      ]]
1125

  
1126
    assert len(exp_logical_ids) == len(disk_info)
1127

  
1128
    map(lambda params: utils.ForceDictType(params,
1129
                                           constants.IDISK_PARAMS_TYPES),
1130
        disk_info)
1131

  
1132
    # Check if empty list of secondaries is rejected
1133
    self.assertRaises(errors.ProgrammerError, gdt, self.lu, constants.DT_DRBD8,
1134
                      "inst827.example.com", "node1334.example.com", [],
1135
                      disk_info, NotImplemented, NotImplemented, 0,
1136
                      self.lu.LogInfo, self.nodegroup.diskparams)
1137

  
1138
    result = gdt(self.lu, constants.DT_DRBD8, "inst827.example.com",
1139
                 "node1334.example.com", ["node12272.example.com"],
1140
                 disk_info, NotImplemented, NotImplemented, 0, self.lu.LogInfo,
1141
                 self.nodegroup.diskparams)
1142

  
1143
    for (idx, disk) in enumerate(result):
1144
      self.assertTrue(isinstance(disk, objects.Disk))
1145
      self.assertEqual(disk.dev_type, constants.LD_DRBD8)
1146
      self.assertEqual(disk.size, disk_info[idx][constants.IDISK_SIZE])
1147
      self.assertEqual(disk.mode, disk_info[idx][constants.IDISK_MODE])
1148

  
1149
      for child in disk.children:
1150
        self.assertTrue(isinstance(disk, objects.Disk))
1151
        self.assertEqual(child.dev_type, constants.LD_LV)
1152
        self.assertTrue(child.children is None)
1153

  
1154
      self.assertEqual(map(operator.attrgetter("logical_id"), disk.children),
1155
                       exp_logical_ids[idx])
1156

  
1157
      self.assertEqual(len(disk.children), 2)
1158
      self.assertEqual(disk.children[0].size, disk.size)
1159
      self.assertEqual(disk.children[1].size, cmdlib.DRBD_META_SIZE)
1160

  
1161
    self.assertEqual(map(operator.attrgetter("iv_name"), result),
1162
                     ["disk/0", "disk/1", "disk/2"])
1163

  
1164
    self.assertEqual(map(operator.attrgetter("logical_id"), result), [
1165
      ("node1334.example.com", "node12272.example.com",
1166
       constants.FIRST_DRBD_PORT, 20, 21, "ec0-secret0"),
1167
      ("node1334.example.com", "node12272.example.com",
1168
       constants.FIRST_DRBD_PORT + 1, 22, 23, "ec0-secret1"),
1169
      ("node1334.example.com", "node12272.example.com",
1170
       constants.FIRST_DRBD_PORT + 2, 24, 25, "ec0-secret2"),
1171
      ])
1172

  
1173

  
907 1174
if __name__ == "__main__":
908 1175
  testutils.GanetiTestProgram()

Also available in: Unified diff