Revision 923b1523

b/lib/cmdlib.py
2300 2300
  return True
2301 2301

  
2302 2302

  
2303
def _GenerateMDDRBDBranch(cfg, vgname, primary, secondary, size, base):
2303
def _GenerateUniqueNames(cfg, exts):
2304
  """Generate a suitable LV name.
2305

  
2306
  This will generate a logical volume name for the given instance.
2307

  
2308
  """
2309
  results = []
2310
  for val in exts:
2311
    new_id = cfg.GenerateUniqueID()
2312
    results.append("%s%s" % (new_id, val))
2313
  return results
2314

  
2315

  
2316
def _GenerateMDDRBDBranch(cfg, primary, secondary, size, names):
2304 2317
  """Generate a drbd device complete with its children.
2305 2318

  
2306 2319
  """
2307 2320
  port = cfg.AllocatePort()
2308
  base = "%s_%s" % (base, port)
2321
  vgname = cfg.GetVGName()
2309 2322
  dev_data = objects.Disk(dev_type="lvm", size=size,
2310
                          logical_id=(vgname, "%s.data" % base))
2323
                          logical_id=(vgname, names[0]))
2311 2324
  dev_meta = objects.Disk(dev_type="lvm", size=128,
2312
                          logical_id=(vgname, "%s.meta" % base))
2325
                          logical_id=(vgname, names[1]))
2313 2326
  drbd_dev = objects.Disk(dev_type="drbd", size=size,
2314 2327
                          logical_id = (primary, secondary, port),
2315 2328
                          children = [dev_data, dev_meta])
2316 2329
  return drbd_dev
2317 2330

  
2318 2331

  
2319
def _GenerateDiskTemplate(cfg, vgname, template_name,
2332
def _GenerateDiskTemplate(cfg, template_name,
2320 2333
                          instance_name, primary_node,
2321 2334
                          secondary_nodes, disk_sz, swap_sz):
2322 2335
  """Generate the entire disk layout for a given template type.
......
2324 2337
  """
2325 2338
  #TODO: compute space requirements
2326 2339

  
2340
  vgname = cfg.GetVGName()
2327 2341
  if template_name == "diskless":
2328 2342
    disks = []
2329 2343
  elif template_name == "plain":
2330 2344
    if len(secondary_nodes) != 0:
2331 2345
      raise errors.ProgrammerError("Wrong template configuration")
2346

  
2347
    names = _GenerateUniqueNames(cfg, [".sda", ".sdb"])
2332 2348
    sda_dev = objects.Disk(dev_type="lvm", size=disk_sz,
2333
                           logical_id=(vgname, "%s.os" % instance_name),
2349
                           logical_id=(vgname, names[0]),
2334 2350
                           iv_name = "sda")
2335 2351
    sdb_dev = objects.Disk(dev_type="lvm", size=swap_sz,
2336
                           logical_id=(vgname, "%s.swap" % instance_name),
2352
                           logical_id=(vgname, names[1]),
2337 2353
                           iv_name = "sdb")
2338 2354
    disks = [sda_dev, sdb_dev]
2339 2355
  elif template_name == "local_raid1":
2340 2356
    if len(secondary_nodes) != 0:
2341 2357
      raise errors.ProgrammerError("Wrong template configuration")
2358

  
2359

  
2360
    names = _GenerateUniqueNames(cfg, [".sda_m1", ".sda_m2",
2361
                                       ".sdb_m1", ".sdb_m2"])
2342 2362
    sda_dev_m1 = objects.Disk(dev_type="lvm", size=disk_sz,
2343
                              logical_id=(vgname, "%s.os_m1" % instance_name))
2363
                              logical_id=(vgname, names[0]))
2344 2364
    sda_dev_m2 = objects.Disk(dev_type="lvm", size=disk_sz,
2345
                              logical_id=(vgname, "%s.os_m2" % instance_name))
2365
                              logical_id=(vgname, names[1]))
2346 2366
    md_sda_dev = objects.Disk(dev_type="md_raid1", iv_name = "sda",
2347 2367
                              size=disk_sz,
2348 2368
                              children = [sda_dev_m1, sda_dev_m2])
2349 2369
    sdb_dev_m1 = objects.Disk(dev_type="lvm", size=swap_sz,
2350
                              logical_id=(vgname, "%s.swap_m1" %
2351
                                          instance_name))
2370
                              logical_id=(vgname, names[2]))
2352 2371
    sdb_dev_m2 = objects.Disk(dev_type="lvm", size=swap_sz,
2353
                              logical_id=(vgname, "%s.swap_m2" %
2354
                                          instance_name))
2372
                              logical_id=(vgname, names[3]))
2355 2373
    md_sdb_dev = objects.Disk(dev_type="md_raid1", iv_name = "sdb",
2356 2374
                              size=swap_sz,
2357 2375
                              children = [sdb_dev_m1, sdb_dev_m2])
......
2360 2378
    if len(secondary_nodes) != 1:
2361 2379
      raise errors.ProgrammerError("Wrong template configuration")
2362 2380
    remote_node = secondary_nodes[0]
2363
    drbd_sda_dev = _GenerateMDDRBDBranch(cfg, vgname,
2364
                                         primary_node, remote_node, disk_sz,
2365
                                         "%s-sda" % instance_name)
2381
    names = _GenerateUniqueNames(cfg, [".sda_data", ".sda_meta",
2382
                                       ".sdb_data", ".sdb_meta"])
2383
    drbd_sda_dev = _GenerateMDDRBDBranch(cfg, primary_node, remote_node,
2384
                                         disk_sz, names[0:2])
2366 2385
    md_sda_dev = objects.Disk(dev_type="md_raid1", iv_name="sda",
2367 2386
                              children = [drbd_sda_dev], size=disk_sz)
2368
    drbd_sdb_dev = _GenerateMDDRBDBranch(cfg, vgname,
2369
                                         primary_node, remote_node, swap_sz,
2370
                                         "%s-sdb" % instance_name)
2387
    drbd_sdb_dev = _GenerateMDDRBDBranch(cfg, primary_node, remote_node,
2388
                                         swap_sz, names[2:4])
2371 2389
    md_sdb_dev = objects.Disk(dev_type="md_raid1", iv_name="sdb",
2372 2390
                              children = [drbd_sdb_dev], size=swap_sz)
2373 2391
    disks = [md_sda_dev, md_sdb_dev]
......
2644 2662
    if self.inst_ip is not None:
2645 2663
      nic.ip = self.inst_ip
2646 2664

  
2647
    disks = _GenerateDiskTemplate(self.cfg, self.cfg.GetVGName(),
2665
    disks = _GenerateDiskTemplate(self.cfg,
2648 2666
                                  self.op.disk_template,
2649 2667
                                  instance, pnode_name,
2650 2668
                                  self.secondaries, self.op.disk_size,
......
2829 2847
    instance = self.instance
2830 2848

  
2831 2849
    remote_node = self.remote_node
2832
    new_drbd = _GenerateMDDRBDBranch(self.cfg, self.cfg.GetVGName(),
2833
                                     instance.primary_node, remote_node,
2834
                                     disk.size, "%s-%s" %
2835
                                     (instance.name, self.op.disk_name))
2850
    lv_names = [".%s_%s" % (disk.iv_name, suf) for suf in ["data", "meta"]]
2851
    names = _GenerateUniqueNames(self.cfg, lv_names)
2852
    new_drbd = _GenerateMDDRBDBranch(self.cfg, instance.primary_node,
2853
                                     remote_node, disk.size, names)
2836 2854

  
2837 2855
    logger.Info("adding new mirror component on secondary")
2838 2856
    #HARDCODE
......
3027 3045
    vgname = cfg.GetVGName()
3028 3046
    for dev in instance.disks:
3029 3047
      size = dev.size
3030
      new_drbd = _GenerateMDDRBDBranch(cfg, vgname, instance.primary_node,
3031
                                       remote_node, size,
3032
                                       "%s-%s" % (instance.name, dev.iv_name))
3048
      lv_names = [".%s_%s" % (dev.iv_name, suf) for suf in ["data", "meta"]]
3049
      names = _GenerateUniqueNames(cfg, lv_names)
3050
      new_drbd = _GenerateMDDRBDBranch(cfg, instance.primary_node,
3051
                                       remote_node, size, names)
3033 3052
      iv_names[dev.iv_name] = (dev, dev.children[0], new_drbd)
3034 3053
      logger.Info("adding new mirror component on secondary for %s" %
3035 3054
                  dev.iv_name)
b/lib/config.py
46 46
from ganeti import rpc
47 47
from ganeti import objects
48 48

  
49
def _my_uuidgen():
50
  """Poor-man's uuidgen using the uuidgen binary.
51

  
52
  """
53
  result = utils.RunCmd(["uuidgen", "-r"])
54
  if result.failed:
55
    return None
56
  return result.stdout.rstrip('\n')
57

  
58

  
59
try:
60
  import uuid
61
  _uuidgen = uuid.uuid4
62
except ImportError:
63
  _uuidgen = _my_uuidgen
64

  
49 65

  
50 66
class ConfigWriter:
51 67
  """The interface to the cluster configuration.
......
61 77
      self._cfg_file = constants.CLUSTER_CONF_FILE
62 78
    else:
63 79
      self._cfg_file = cfg_file
80
    self._temporary_ids = set()
64 81

  
65 82
  # this method needs to be static, so that we can call it on the class
66 83
  @staticmethod
......
93 110
      raise errors.ConfigurationError, ("Can't generate unique MAC")
94 111
    return mac
95 112

  
113
  def _ComputeAllLVs(self):
114
    """Compute the list of all LVs.
115

  
116
    """
117
    self._OpenConfig()
118
    self._ReleaseLock()
119
    lvnames = set()
120
    for instance in self._config_data.instances.values():
121
      node_data = instance.MapLVsByNode()
122
      for lv_list in node_data.values():
123
        lvnames.update(lv_list)
124
    return lvnames
125

  
126
  def GenerateUniqueID(self, exceptions=None):
127
    """Generate an unique disk name.
128

  
129
    This checks the current node, instances and disk names for
130
    duplicates.
131

  
132
    Args:
133
      - exceptions: a list with some other names which should be checked
134
                    for uniqueness (used for example when you want to get
135
                    more than one id at one time without adding each one in
136
                    turn to the config file
137

  
138
    Returns: the unique id as a string
139

  
140
    """
141
    existing = set()
142
    existing.update(self._temporary_ids)
143
    existing.update(self._ComputeAllLVs())
144
    existing.update(self._config_data.instances.keys())
145
    existing.update(self._config_data.nodes.keys())
146
    if exceptions is not None:
147
      existing.update(exceptions)
148
    retries = 64
149
    while retries > 0:
150
      unique_id = _uuidgen()
151
      if unique_id not in existing and unique_id is not None:
152
        break
153
    else:
154
      raise errors.ConfigurationError, ("Not able generate an unique ID"
155
                                        " (last tried ID: %s" % unique_id)
156
    self._temporary_ids.add(unique_id)
157
    return unique_id
158

  
96 159
  def _AllMACs(self):
97 160
    """Return all MACs present in the config.
98 161

  
......
133 196
          seen_macs.append(nic.mac)
134 197
    return result
135 198

  
136

  
137 199
  def SetDiskID(self, disk, node_name):
138 200
    """Convert the unique ID to the ID needed on the target nodes.
139 201

  
......
235 297
    if not isinstance(instance, objects.Instance):
236 298
      raise errors.ProgrammerError("Invalid type passed to AddInstance")
237 299

  
300
    all_lvs = instance.MapLVsByNode()
301
    logger.Info("Instance '%s' DISK_LAYOUT: %s" % (instance.name, all_lvs))
302

  
238 303
    self._OpenConfig()
239 304
    self._config_data.instances[instance.name] = instance
240 305
    self._WriteConfig()

Also available in: Unified diff