Revision c3589cf8
b/lib/cmdlib.py | ||
---|---|---|
5804 | 5804 |
not constants.ENABLE_FILE_STORAGE): |
5805 | 5805 |
raise errors.OpPrereqError("File storage disabled at configure time", |
5806 | 5806 |
errors.ECODE_INVAL) |
5807 |
# check disk information: either all adopt, or no adopt |
|
5808 |
has_adopt = has_no_adopt = False |
|
5809 |
for disk in self.op.disks: |
|
5810 |
if "adopt" in disk: |
|
5811 |
has_adopt = True |
|
5812 |
else: |
|
5813 |
has_no_adopt = True |
|
5814 |
if has_adopt and has_no_adopt: |
|
5815 |
raise errors.OpPrereqError("Either all disks have are adoped or none is", |
|
5816 |
errors.ECODE_INVAL) |
|
5817 |
if has_adopt: |
|
5818 |
if self.op.disk_template != constants.DT_PLAIN: |
|
5819 |
raise errors.OpPrereqError("Disk adoption is only supported for the" |
|
5820 |
" 'plain' disk template", |
|
5821 |
errors.ECODE_INVAL) |
|
5822 |
if self.op.iallocator is not None: |
|
5823 |
raise errors.OpPrereqError("Disk adoption not allowed with an" |
|
5824 |
" iallocator script", errors.ECODE_INVAL) |
|
5825 |
if self.op.mode == constants.INSTANCE_IMPORT: |
|
5826 |
raise errors.OpPrereqError("Disk adoption not allowed for" |
|
5827 |
" instance import", errors.ECODE_INVAL) |
|
5828 |
|
|
5829 |
self.adopt_disks = has_adopt |
|
5807 | 5830 |
|
5808 | 5831 |
def ExpandNames(self): |
5809 | 5832 |
"""ExpandNames for CreateInstance. |
... | ... | |
5958 | 5981 |
except (TypeError, ValueError): |
5959 | 5982 |
raise errors.OpPrereqError("Invalid disk size '%s'" % size, |
5960 | 5983 |
errors.ECODE_INVAL) |
5961 |
self.disks.append({"size": size, "mode": mode}) |
|
5984 |
new_disk = {"size": size, "mode": mode} |
|
5985 |
if "adopt" in disk: |
|
5986 |
new_disk["adopt"] = disk["adopt"] |
|
5987 |
self.disks.append(new_disk) |
|
5962 | 5988 |
|
5963 | 5989 |
# file storage checks |
5964 | 5990 |
if (self.op.file_driver and |
... | ... | |
6227 | 6253 |
req_size = _ComputeDiskSize(self.op.disk_template, |
6228 | 6254 |
self.disks) |
6229 | 6255 |
|
6230 |
# Check lv size requirements |
|
6231 |
if req_size is not None: |
|
6256 |
# Check lv size requirements, if not adopting
|
|
6257 |
if req_size is not None and not self.adopt_disks:
|
|
6232 | 6258 |
nodeinfo = self.rpc.call_node_info(nodenames, self.cfg.GetVGName(), |
6233 | 6259 |
self.op.hypervisor) |
6234 | 6260 |
for node in nodenames: |
... | ... | |
6245 | 6271 |
(node, vg_free, req_size), |
6246 | 6272 |
errors.ECODE_NORES) |
6247 | 6273 |
|
6274 |
if self.adopt_disks: # instead, we must check the adoption data |
|
6275 |
all_lvs = set([i["adopt"] for i in self.disks]) |
|
6276 |
if len(all_lvs) != len(self.disks): |
|
6277 |
raise errors.OpPrereqError("Duplicate volume names given for adoption", |
|
6278 |
errors.ECODE_INVAL) |
|
6279 |
for lv_name in all_lvs: |
|
6280 |
try: |
|
6281 |
self.cfg.ReserveLV(lv_name, self.proc.GetECId()) |
|
6282 |
except errors.ReservationError: |
|
6283 |
raise errors.OpPrereqError("LV named %s used by another instance" % |
|
6284 |
lv_name, errors.ECODE_NOTUNIQUE) |
|
6285 |
|
|
6286 |
node_lvs = self.rpc.call_lv_list([pnode.name], |
|
6287 |
self.cfg.GetVGName())[pnode.name] |
|
6288 |
node_lvs.Raise("Cannot get LV information from node %s" % pnode.name) |
|
6289 |
node_lvs = node_lvs.payload |
|
6290 |
delta = all_lvs.difference(node_lvs.keys()) |
|
6291 |
if delta: |
|
6292 |
raise errors.OpPrereqError("Missing logical volume(s): %s" % |
|
6293 |
utils.CommaJoin(delta), |
|
6294 |
errors.ECODE_INVAL) |
|
6295 |
online_lvs = [lv for lv in all_lvs if node_lvs[lv][2]] |
|
6296 |
if online_lvs: |
|
6297 |
raise errors.OpPrereqError("Online logical volumes found, cannot" |
|
6298 |
" adopt: %s" % utils.CommaJoin(online_lvs), |
|
6299 |
errors.ECODE_STATE) |
|
6300 |
# update the size of disk based on what is found |
|
6301 |
for dsk in self.disks: |
|
6302 |
dsk["size"] = int(float(node_lvs[dsk["adopt"]][0])) |
|
6303 |
|
|
6248 | 6304 |
_CheckHVParams(self, nodenames, self.op.hypervisor, self.op.hvparams) |
6249 | 6305 |
|
6250 | 6306 |
# os verification |
... | ... | |
6313 | 6369 |
hypervisor=self.op.hypervisor, |
6314 | 6370 |
) |
6315 | 6371 |
|
6316 |
feedback_fn("* creating instance disks...") |
|
6317 |
try: |
|
6318 |
_CreateDisks(self, iobj) |
|
6319 |
except errors.OpExecError: |
|
6320 |
self.LogWarning("Device creation failed, reverting...") |
|
6372 |
if self.adopt_disks: |
|
6373 |
# rename LVs to the newly-generated names; we need to construct |
|
6374 |
# 'fake' LV disks with the old data, plus the new unique_id |
|
6375 |
tmp_disks = [objects.Disk.FromDict(v.ToDict()) for v in disks] |
|
6376 |
rename_to = [] |
|
6377 |
for t_dsk, a_dsk in zip (tmp_disks, self.disks): |
|
6378 |
rename_to.append(t_dsk.logical_id) |
|
6379 |
t_dsk.logical_id = (t_dsk.logical_id[0], a_dsk["adopt"]) |
|
6380 |
self.cfg.SetDiskID(t_dsk, pnode_name) |
|
6381 |
result = self.rpc.call_blockdev_rename(pnode_name, |
|
6382 |
zip(tmp_disks, rename_to)) |
|
6383 |
result.Raise("Failed to rename adoped LVs") |
|
6384 |
else: |
|
6385 |
feedback_fn("* creating instance disks...") |
|
6321 | 6386 |
try: |
6322 |
_RemoveDisks(self, iobj) |
|
6323 |
finally: |
|
6324 |
self.cfg.ReleaseDRBDMinors(instance) |
|
6325 |
raise |
|
6387 |
_CreateDisks(self, iobj) |
|
6388 |
except errors.OpExecError: |
|
6389 |
self.LogWarning("Device creation failed, reverting...") |
|
6390 |
try: |
|
6391 |
_RemoveDisks(self, iobj) |
|
6392 |
finally: |
|
6393 |
self.cfg.ReleaseDRBDMinors(instance) |
|
6394 |
raise |
|
6326 | 6395 |
|
6327 | 6396 |
feedback_fn("adding instance %s to cluster config" % instance) |
6328 | 6397 |
|
... | ... | |
6360 | 6429 |
raise errors.OpExecError("There are some degraded disks for" |
6361 | 6430 |
" this instance") |
6362 | 6431 |
|
6363 |
feedback_fn("creating os for instance %s on node %s" % |
|
6364 |
(instance, pnode_name)) |
|
6365 |
|
|
6366 |
if iobj.disk_template != constants.DT_DISKLESS: |
|
6432 |
if iobj.disk_template != constants.DT_DISKLESS and not self.adopt_disks: |
|
6367 | 6433 |
if self.op.mode == constants.INSTANCE_CREATE: |
6368 | 6434 |
feedback_fn("* running the instance OS create scripts...") |
6369 | 6435 |
# FIXME: pass debug option from opcode to backend |
Also available in: Unified diff