Revision c8a96ae7 lib/cmdlib.py
b/lib/cmdlib.py | ||
---|---|---|
5440 | 5440 |
HTYPE = constants.HTYPE_INSTANCE |
5441 | 5441 |
REQ_BGL = False |
5442 | 5442 |
|
5443 |
def CheckArguments(self): |
|
5444 |
# normalise the disk list |
|
5445 |
self.op.disks = sorted(frozenset(self.op.disks)) |
|
5446 |
|
|
5443 | 5447 |
def ExpandNames(self): |
5444 | 5448 |
self._ExpandAndLockInstance() |
5449 |
self.recalculate_locks[locking.LEVEL_NODE] = constants.LOCKS_APPEND |
|
5450 |
if self.op.nodes: |
|
5451 |
self.op.nodes = [_ExpandNodeName(self.cfg, n) for n in self.op.nodes] |
|
5452 |
self.needed_locks[locking.LEVEL_NODE] = list(self.op.nodes) |
|
5453 |
else: |
|
5454 |
self.needed_locks[locking.LEVEL_NODE] = [] |
|
5455 |
|
|
5456 |
def DeclareLocks(self, level): |
|
5457 |
if level == locking.LEVEL_NODE: |
|
5458 |
# if we replace the nodes, we only need to lock the old primary, |
|
5459 |
# otherwise we need to lock all nodes for disk re-creation |
|
5460 |
primary_only = bool(self.op.nodes) |
|
5461 |
self._LockInstancesNodes(primary_only=primary_only) |
|
5445 | 5462 |
|
5446 | 5463 |
def BuildHooksEnv(self): |
5447 | 5464 |
"""Build hooks env. |
... | ... | |
5462 | 5479 |
instance = self.cfg.GetInstanceInfo(self.op.instance_name) |
5463 | 5480 |
assert instance is not None, \ |
5464 | 5481 |
"Cannot retrieve locked instance %s" % self.op.instance_name |
5465 |
_CheckNodeOnline(self, instance.primary_node) |
|
5482 |
if self.op.nodes: |
|
5483 |
if len(self.op.nodes) != len(instance.all_nodes): |
|
5484 |
raise errors.OpPrereqError("Instance %s currently has %d nodes, but" |
|
5485 |
" %d replacement nodes were specified" % |
|
5486 |
(instance.name, len(instance.all_nodes), |
|
5487 |
len(self.op.nodes)), |
|
5488 |
errors.ECODE_INVAL) |
|
5489 |
assert instance.disk_template != constants.DT_DRBD8 or \ |
|
5490 |
len(self.op.nodes) == 2 |
|
5491 |
assert instance.disk_template != constants.DT_PLAIN or \ |
|
5492 |
len(self.op.nodes) == 1 |
|
5493 |
primary_node = self.op.nodes[0] |
|
5494 |
else: |
|
5495 |
primary_node = instance.primary_node |
|
5496 |
_CheckNodeOnline(self, primary_node) |
|
5466 | 5497 |
|
5467 | 5498 |
if instance.disk_template == constants.DT_DISKLESS: |
5468 | 5499 |
raise errors.OpPrereqError("Instance '%s' has no disks" % |
5469 | 5500 |
self.op.instance_name, errors.ECODE_INVAL) |
5470 |
_CheckInstanceDown(self, instance, "cannot recreate disks") |
|
5501 |
# if we replace nodes *and* the old primary is offline, we don't |
|
5502 |
# check |
|
5503 |
assert instance.primary_node in self.needed_locks[locking.LEVEL_NODE] |
|
5504 |
old_pnode = self.cfg.GetNodeInfo(instance.primary_node) |
|
5505 |
if not (self.op.nodes and old_pnode.offline): |
|
5506 |
_CheckInstanceDown(self, instance, "cannot recreate disks") |
|
5471 | 5507 |
|
5472 | 5508 |
if not self.op.disks: |
5473 | 5509 |
self.op.disks = range(len(instance.disks)) |
... | ... | |
5476 | 5512 |
if idx >= len(instance.disks): |
5477 | 5513 |
raise errors.OpPrereqError("Invalid disk index passed '%s'" % idx, |
5478 | 5514 |
errors.ECODE_INVAL) |
5479 |
|
|
5515 |
if self.op.disks != range(len(instance.disks)) and self.op.nodes: |
|
5516 |
raise errors.OpPrereqError("Can't recreate disks partially and" |
|
5517 |
" change the nodes at the same time", |
|
5518 |
errors.ECODE_INVAL) |
|
5480 | 5519 |
self.instance = instance |
5481 | 5520 |
|
5482 | 5521 |
def Exec(self, feedback_fn): |
5483 | 5522 |
"""Recreate the disks. |
5484 | 5523 |
|
5485 | 5524 |
""" |
5525 |
# change primary node, if needed |
|
5526 |
if self.op.nodes: |
|
5527 |
self.instance.primary_node = self.op.nodes[0] |
|
5528 |
self.LogWarning("Changing the instance's nodes, you will have to" |
|
5529 |
" remove any disks left on the older nodes manually") |
|
5530 |
|
|
5486 | 5531 |
to_skip = [] |
5487 |
for idx, _ in enumerate(self.instance.disks):
|
|
5532 |
for idx, disk in enumerate(self.instance.disks):
|
|
5488 | 5533 |
if idx not in self.op.disks: # disk idx has not been passed in |
5489 | 5534 |
to_skip.append(idx) |
5490 | 5535 |
continue |
5536 |
# update secondaries for disks, if needed |
|
5537 |
if self.op.nodes: |
|
5538 |
if disk.dev_type == constants.LD_DRBD8: |
|
5539 |
# need to update the nodes |
|
5540 |
assert len(self.op.nodes) == 2 |
|
5541 |
logical_id = list(disk.logical_id) |
|
5542 |
logical_id[0] = self.op.nodes[0] |
|
5543 |
logical_id[1] = self.op.nodes[1] |
|
5544 |
disk.logical_id = tuple(logical_id) |
|
5545 |
|
|
5546 |
if self.op.nodes: |
|
5547 |
self.cfg.Update(self.instance, feedback_fn) |
|
5491 | 5548 |
|
5492 | 5549 |
_CreateDisks(self, self.instance, to_skip=to_skip) |
5493 | 5550 |
|
Also available in: Unified diff